circuits_uart_midi_framing/lib/circuits/uart/framing/midi.ex
James Harton b446da8bb2
All checks were successful
continuous-integration/drone Build is passing
chore: migrate to local.
2024-06-24 12:51:31 +12:00

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