45 lines
1.2 KiB
Elixir
45 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}
|
|
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
|