Working sending to DKAH

only send a tuple of 3 floats to the "/webosc/gyro" channel
parent 4eff3346
use Mix.Config
config :grains_engine,
osc_client_ip: {127,0,0,1},
osc_client_port: 8001
osc_client_ip: {192, 168, 1, 58},
osc_client_port: 47122,
phoenix_url: "ws://localhost:4000/socket/websocket?token=foobar"
use Mix.Config
config :grains_engine,
osc_client_ip: {127,0,0,1},
osc_client_port: 8001,
phoenix_url: "ws://grains.switch.ch/socket/websocket?token=foobar"
......@@ -2,4 +2,5 @@ use Mix.Config
config :grains_engine,
osc_client_ip: {127,0,0,1},
osc_client_port: 8001
osc_client_port: 8001,
phoenix_url: "ws://localhost:4000/socket/websocket?token=foobar"
......@@ -12,7 +12,14 @@ defmodule GrainsEngine do
Logger.info "Application starting"
import Supervisor.Spec, warn: false
ip = Application.fetch_env!(:grains_engine, :osc_client_ip)
port = Application.fetch_env!(:grains_engine, :osc_client_port)
Logger.info "Supervising #{port}"
children = [
worker(GrainsEngine.OscSender, [ip, port]),
supervisor(GrainsEngine.PerformanceSupervisor, []),
worker(GrainsEngine.SocketClient, [])
]
......
......@@ -4,24 +4,28 @@ defmodule GrainsEngine.Application do
@moduledoc false
use Application
require Logger
def start(_type, args) do
import Supervisor.Spec, warn: false
# import Supervisor.Spec, warn: false
ip = Application.fetch_env!(:grains_engine, :osc_client_ip)
port = Application.fetch_env!(:grains_engine, :osc_client_port)
IO.puts "Supervising #{port}"
# ip = Application.fetch_env!(:grains_engine, :osc_client_ip)
# port = Application.fetch_env!(:grains_engine, :osc_client_port)
# Logger.info "Supervising #{port}"
# Define workers and child supervisors to be supervised
children = [
# Starts a worker by calling: GrainsEngine.Worker.start_link(arg1, arg2, arg3)
# worker(GrainsEngine.Worker, [arg1, arg2, arg3]),
worker(GrainsEngine.OscSender, [:foo, ip, port])
]
# # Define workers and child supervisors to be supervised
# children = [
# # Starts a worker by calling: GrainsEngine.Worker.start_link(arg1, arg2, arg3)
# # worker(GrainsEngine.Worker, [arg1, arg2, arg3]),
# worker(GrainsEngine.OscSender, [ip, port]),
# supervisor(GrainsEngine.PerformanceSupervisor, [])
# ]
# See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# for other strategies and supported options
opts = [strategy: :one_for_one, name: GrainsEngine.Supervisor]
Supervisor.start_link(children, opts)
# Logger.warn "Starting stuff"
# # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html
# # for other strategies and supported options
# opts = [strategy: :one_for_one, name: GrainsEngine.PerformanceSupervisor]
# Supervisor.start_link(children, opts)
end
end
2
defmodule GrainsEngine.PerformanceSupervisor do
use Supervisor
require Logger
def start_link do
Logger.info "Starting PerformanceSupervisor"
Supervisor.start_link(__MODULE__, [], name: :grains_supervisor)
end
def start_performance(name) do
Supervisor.start_child(:grains_supervisor, [name])
end
def init(_) do
children = [
worker(GrainsEngine.Performance, [])
]
supervise(children, strategy: :simple_one_for_one)
end
end
......@@ -2,27 +2,30 @@ defmodule GrainsEngine.SocketClient do
@moduledoc false
require Logger
alias Phoenix.Channels.GenSocketClient
alias GrainsEngine.{Performance, PerformanceSupervisor }
@behaviour GenSocketClient
# "ws://localhost:4000/socket/websocket?token=foobar"
def start_link() do
phoenix_url = Application.fetch_env!(:grains_engine, :phoenix_url)
Logger.info "SocketClient.start_link"
GenSocketClient.start_link(
__MODULE__,
Phoenix.Channels.GenSocketClient.Transport.WebSocketClient,
"ws://localhost:4000/socket/websocket?token=foobar"
)
__MODULE__,
Phoenix.Channels.GenSocketClient.Transport.WebSocketClient,
phoenix_url
)
end
def init(url) do
Logger.info "SocketClient.init #{url}"
{:connect, url, %{first_join: true, ping_ref: 1}}
{:connect, url, %{}}
end
def handle_connected(transport, state) do
Logger.info("connected")
GenSocketClient.join(transport, "ping")
Logger.info("connected, joining")
GenSocketClient.join(transport, "osc")
{:ok, state}
end
......@@ -34,13 +37,13 @@ defmodule GrainsEngine.SocketClient do
def handle_joined(topic, _payload, _transport, state) do
Logger.info("joined the topic #{topic}")
if state.first_join do
:timer.send_interval(:timer.seconds(1), self(), :ping_server)
{:ok, %{state | first_join: false, ping_ref: 1}}
else
{:ok, %{state | ping_ref: 1}}
end
{:ok, state}
# if state.first_join do
# :timer.send_interval(:timer.seconds(10), self(), :ping_server)
# {:ok, %{state | first_join: false, ping_ref: 1}}
# else
# {:ok, %{state | ping_ref: 1}}
# end
end
def handle_join_error(topic, payload, _transport, state) do
......@@ -54,11 +57,56 @@ defmodule GrainsEngine.SocketClient do
{:ok, state}
end
def handle_message("osc", "presence", payload, _transport, state) do
user = payload["user"]
Logger.info("Starting Performance for #{user}")
PerformanceSupervisor.start_performance(user)
{:ok, state}
end
def handle_message("osc", "performance", payload, _transport, state) do
Logger.info "Performance event received"
Logger.info inspect(payload)
{:ok, state}
end
def handle_message("osc", "clock", _payload, _transport, state) do
channel = "/clock"
message = 1
GrainsEngine.OscSender.send_raw(channel, message)
message = 0
GrainsEngine.OscSender.send_raw(channel, message)
{:ok, state}
end
def handle_message("osc", "slider", payload, _transport, state) do
Logger.warn("Slider: #{inspect payload}")
# Enum.each(payload, fn({ user, values} ) ->
# Enum.each(values, fn({param, value}) ->
# GrainsEngine.OscSender.send_osc_value(user, param, value)
# end)
# end)
Enum.each(payload, fn({user, value}) ->
GrainsEngine.OscSender.send_raw("/webosc/gyro", value)
end)
{:ok, state}
end
def handle_message(topic, event, payload, _transport, state) do
Logger.warn("message on topic #{topic}: #{event} #{inspect payload}")
Logger.warn("message on topic #{topic}: #{inspect event} #{inspect payload}")
{:ok, state}
end
def handle_reply("ping", _ref, %{"status" => "ok"} = payload, _transport, state) do
Logger.info("server pong ##{payload["response"]["ping_ref"]}")
{:ok, state}
......
defmodule GrainsEngine.OscSender do
alias GrainsEngine.{OscSender, Player}
alias GrainsEngine.{OscSender, Player, Grain}
@doc """
starts a new sending process for OSC on `ip` (tuple) and `port`
"""
def start_link(name, ip, port) do
Agent.start_link(fn -> {ip, port} end, name: name)
def start_link(ip, port) do
Agent.start_link(fn -> {ip, port} end, name: __MODULE__)
end
@doc """
Sends an OSC `message` with `value` on a given `channel`
"""
def send(pid, channel, message) do
Agent.get(pid, fn {ip, port} ->
IO.puts "sending to #{channel}"
def send(channel, message) do
Agent.get(__MODULE__, fn {ip, port} ->
IO.puts "sending to #{channel} #{inspect(message)}"
ExOsc.Sender.send_message(ip, port, {channel, message})
{ip, port}
end)
end
def send_player(pid, player) do
def send_grain(name, grain) do
Grain.get_params(grain)
|> Enum.each(fn {key, value} ->
send_osc_value(name, key, value)
end)
end
def send_osc_value(name, key, value) do
channel = "/#{name}/#{key}"
OscSender.send_raw(channel, value)
end
def send_raw(channel, value) when is_integer(value) do
OscSender.send(channel, {:osc_float, value / 1})
end
def send_raw(channel, value) when is_float(value) do
OscSender.send(channel, {:osc_float, value})
end
def send_raw(channel, value) when is_tuple(value) or is_map(value) do
OscSender.send(channel, build_osc_tuple(value))
end
def send_raw(_channel, _value) do
end
def build_osc_tuple(values) do
values
|> Enum.map(fn v ->
build_osc_value(v)
end)
end
# def build_osc_tuple(values) when is_map(values) do
# values
# |> Enum.map(fn v ->
# build_osc_value(v)
# end)
# end
def build_osc_value(v) when is_integer(v) do
{:osc_float, v / 1}
end
def build_osc_value(v) when is_float(v) do
{:osc_float, v}
end
def build_osc_value(map = {_k, v}) when is_tuple(map) do
build_osc_value(v)
end
def send_player(player) do
name = Player.name(player)
Player.get_values(player)
|> Enum.each(fn {k,v} ->
channel = "/#{name}/#{k}"
OscSender.send(pid, channel, {:osc_integer, v})
OscSender.send(channel, {:osc_float, v})
end)
......
......@@ -2,39 +2,56 @@ defmodule GrainsEngine.Performance do
use GenServer
defstruct player: :none
alias GrainsEngine.Performance
alias GrainsEngine.Player
alias GrainsEngine.Grain
def start_link(name) when is_binary(name) and byte_size(name) > 0 do
GenServer.start_link(__MODULE__, name, name: {:global, "perf:#{name}"})
def start_link(name) do
GenServer.start_link(__MODULE__, [], name: via_tuple(name))
end
def stop(pid) do
GenServer.cast(pid, :stop)
defp via_tuple(performance_name) do
{:via, :gproc, {:n, :l, {:performance, performance_name}}}
end
def set_values(performance_name, params) do
GenServer.cast(via_tuple(performance_name), {:set_values, params})
end
def get_values(performance_name) do
GenServer.call(via_tuple(performance_name), :get_values)
end
def init(name) do
{:ok, player} = Player.start_link(name)
Player.set_name(player, name)
{:ok, %Performance{player: player}}
def send_values(performance_name) do
GenServer.cast(via_tuple(performance_name), {:send_values, performance_name})
end
def handle_cast(:stop, state) do
{:stop, :normal, state}
# SERVER
def init(params) do
{:ok, grain} = Grain.start_link(["s1", "s2"])
{:ok, grain}
end
def handle_cast({:set_values, params}, grain) do
Enum.each(params, fn {k, v} ->
Grain.set_value(grain, k, v)
end)
{:noreply, grain}
end
def handle_call(:demo, _from, state) do
{:reply, state, state}
def handle_cast({:send_values, name}, grain) do
IO.puts("sending: #{name} #{inspect grain}")
GrainsEngine.OscSender.send_grain(name, grain)
{:noreply, grain}
end
def call_demo(pid) do
GenServer.call(pid, :demo)
def handle_call(:get_values, _from, grain) do
{:reply, Grain.get_params(grain), grain}
end
###
end
......@@ -15,7 +15,8 @@ defmodule GrainsEngine.Mixfile do
# Type "mix help compile.app" for more information
def application do
# Specify extra applications you'll use from Erlang/Elixir
[extra_applications: [:logger, :ex_osc, :phoenix_gen_socket_client, :websocket_client],
[extra_applications: [:logger, :ex_osc, :phoenix_gen_socket_client, :websocket_client, :gproc,
:portmidi],
mod: {GrainsEngine, []}]
end
......@@ -33,6 +34,8 @@ defmodule GrainsEngine.Mixfile do
{:phoenix_gen_socket_client, "~> 1.0.0"},
{:websocket_client, github: "sanmiguel/websocket_client", tag: "1.1.0"},
{:poison, "~> 1.5.2"},
{:gproc, "0.3.1"},
{:portmidi, "~> 5.0"},
{:mix_test_watch, "~> 0.3", only: :dev, runtime: false}]
end
end
%{"ex_osc": {:git, "git://github.com/jwarwick/ex_osc.git", "2f695afc837670d022a90a7954a2cf53d023ad80", []},
"fs": {:hex, :fs, "2.12.0", "ad631efacc9a5683c8eaa1b274e24fa64a1b8eb30747e9595b93bec7e492e25e", [:rebar3], []},
"gproc": {:hex, :gproc, "0.3.1", "ec14f40cb941bde3f940de59c11e59beb2977e90dbae72fab3ddf77743fd4ea9", [:rebar], []},
"mix_test_watch": {:hex, :mix_test_watch, "0.3.3", "70859889a8d1d43d1b75d69d87258a301f43209a17787cdb2bd9cab42adf271d", [:mix], [{:fs, "~> 2.12", [hex: :fs, optional: false]}]},
"phoenix_gen_socket_client": {:hex, :phoenix_gen_socket_client, "1.0.0", "621d9537ccaea71960de9da6483b03817646018471f5e1d5efd7fcc65b1af854", [:mix], []},
"poison": {:hex, :poison, "1.5.2", "560bdfb7449e3ddd23a096929fb9fc2122f709bcc758b2d5d5a5c7d0ea848910", [:mix], []},
"portmidi": {:hex, :portmidi, "5.1.1", "7b41e69c5d6364d143dc3663080750127fc0497d2bbe2d1690b7703d7e639482", [:make, :mix], []},
"websocket_client": {:git, "https://github.com/sanmiguel/websocket_client.git", "16cd139a71d99813ec0c0cd1d8cb92dbde93d9c7", [tag: "1.1.0"]}}
......@@ -5,22 +5,31 @@ defmodule OscSenderTest do
doctest GrainsEngine.OscSender
alias GrainsEngine.{OscSender, Player}
describe "populated Player" do
setup do
{:ok, player} = Player.start_link("frank", ["foo", "bar"])
values = %{foo: 1, bar: 3}
Player.update_parameters(player, values)
end
describe "convert values to osc values" do
test "sends the OSC values to channel", %{player: player} do
OscSender.send_player(:foo, player)
test "with floats" do
assert OscSender.build_osc_value(0.5) == {:osc_float, 0.5}
end
assert true == true
test "with integers" do
assert OscSender.build_osc_value(5) == {:osc_float, 5.0}
end
end
describe "convert a raw tuple" do
assert OscSender.build_osc_tuple([0.1, 0.2, 3.0]) == [osc_float: 0.1,
osc_float: 0.2,
osc_float: 3.0]
end
describe "convert a map" do
assert OscSender.build_osc_tuple( %{"pitch" => 73, "roll" => 74, "yaw" => 3} ) == [osc_float: 73.0,
osc_float: 74.0,
osc_float: 3.0]
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment