Packages

Read and write audio over serial port.

Current section

Files

Jump to
ecall_audio lib ecall_audio.ex
Raw

lib/ecall_audio.ex

defmodule Ecall.Audio do
use GenServer
require Logger
@moduledoc """
Capture and write audio from/to USB device.
"""
defmodule State do
@moduledoc false
# from: pid of client (where the audio data is sent)
# pid: pid of serial port process
defstruct from: nil,
pid: nil
end
@doc """
Start up a Audio GenServer.
"""
@spec start_link([term]) :: {:ok, pid} | {:error, term}
def start_link(opts \\ []) do
GenServer.start_link(__MODULE__, [], opts)
end
@doc """
open a serial device able to receive and
write audio
"""
@spec open_device(GenServer.server(), binary, [term]) :: :ok | {:error, term}
def open_device(pid, name, opts \\ []) do
GenServer.call(pid, {:open, name, opts})
end
@doc """
write audio to serial port
"""
@spec write(GenServer.server(), binary) :: :ok | {:error, term}
def write(pid, data) do
GenServer.call(pid, {:write, data})
end
@doc """
write audio to serial port
"""
@spec read(GenServer.server()) :: {:ok, binary} | {:error, term}
def read(pid) do
GenServer.call(pid, :read, 15000)
end
@doc """
close the serial port
"""
@spec close_device(GenServer.server()) :: :ok | {:error, term}
def close_device (pid) do
GenServer.call(pid, :close)
end
#gen_server callbacks
def init([]) do
case Circuits.UART.start_link do
{:ok, pid} ->
state = %State{pid: pid}
{:ok, state}
{:error, cause} ->
{:stop, cause}
end
end
def handle_call({:open, name, opts}, {from_pid, _}, state) do
options = Keyword.merge([speed: 115200, active: true], opts)
case Circuits.UART.open(state.pid, name, options) do
:ok ->
new_state = %{state | from: from_pid}
{:reply, :ok, new_state}
ret ->
{:reply, ret, state}
end
end
def handle_call(:close, _from, state) do
response = Circuits.UART.close(state.pid)
{:reply, response, state}
end
def handle_call({:write, data}, _from, state) do
response = Circuits.UART.write(state.pid, data)
{:reply, response, state}
end
def handle_call(:read, _from, state) do
#Circuits.UART.flush(state.pid,:receive)
response = Circuits.UART.read(state.pid,10000)
{:reply, response, state}
end
def handle_info({:circuits_uart, _port, data}, state) do
send(state.from, {:ecall_audio,data})
{:noreply, state}
end
def typeof(self) do
cond do
is_float(self) -> "float"
is_number(self) -> "number"
is_atom(self) -> "atom"
is_boolean(self) -> "boolean"
is_binary(self) -> "binary"
is_function(self) -> "function"
is_list(self) -> "list"
is_tuple(self) -> "tuple"
true -> "idunno"
end
end
end