circuits_uart_midi_framing/lib/circuits/uart/framing/midi.ex
2020-05-04 21:26:45 +12:00

46 lines
1.2 KiB
Elixir

defmodule Circuits.UART.Framing.MIDI do
@behaviour Circuits.UART.Framing
alias __MODULE__.Buffer
@moduledoc """
Implements framing for the MIDI protocol.
It doesn't decode any messages, it simply splits incoming serial frames apart
into individual MIDI messages as per the specification.
"""
@impl true
def init(_args), do: {:ok, Buffer.init()}
@doc """
Basically a no-op from a framing point of view. There's no intra-message
delimeter required, so we simply return the data unchanged.
"""
@impl true
def add_framing(data, state) do
{:ok, data, state}
end
@doc """
Process incoming data and break it apart into separate MIDI packets.
"""
@impl true
def remove_framing(data, %Buffer{} = buffer) do
buffer = Buffer.append(buffer, data)
case Buffer.get_packets(buffer) do
{:ok, messages, %Buffer{buffer: <<>>} = buffer} -> {:ok, messages, buffer}
{:ok, messages, %Buffer{} = buffer} -> {:in_frame, messages, buffer}
{:error, reason} -> {:error, reason}
end
end
@impl true
def frame_timeout(buffer), do: buffer
@impl true
def flush(direction, _buffer) when direction == :receive or direction == :both,
do: Buffer.init()
def flush(:transmit, buffer), do: buffer
end