目標
- Elixirでモグラたたきを作る
- PioneerDjのDDJ-FLX4を使う
仕様
- Pad1〜Pad8のランダムでLED点灯
- LEDが点灯したPadを押すとカウント対象
- 1Padの点灯時間は500ミリ秒
- 30回点灯する
ソース
DDJ-FLX4のライブラリ
lib/ddj.ex
defmodule Ddj do
@moduledoc """
Documentation for `Ddj`.
"""
def led_on, do: "7F"
def led_off, do: "00"
def pad1, do: "00"
def pad2, do: "01"
def pad3, do: "02"
def pad4, do: "03"
def pad5, do: "04"
def pad6, do: "05"
def pad7, do: "06"
def pad8, do: "07"
def deck1, do: "97"
def deck2, do: "99"
def pad_list, do: [pad1(), pad2(), pad3(), pad4(), pad5(), pad6(), pad7(), pad8()]
def open(inout \\ :output) do
{_, output} = PortMidi.open(inout, "DDJ-FLX4 MIDI 1")
output
end
def close(output, inout \\ :output) do
PortMidi.close(inout, output)
end
def send_midi(v, output) do
Enum.map(v, fn x -> hex_to_dec(x) end)
|> List.to_tuple()
|> then(&PortMidi.write(output, &1))
end
def hex_to_dec(hex), do: String.to_integer(hex, 16)
def pad_led(output, deck, pad, led_sw) do
[deck, pad, led_sw]
|> send_midi(output)
end
end
モグラたたきゲーム本体
defmodule Mogu do
@moduledoc """
Documentation for `Mogu`.
"""
import Ddj
def start() do
output = open()
input = open(:input)
PortMidi.listen(input, self())
pad_randoms(output, input)
|> Enum.count(fn x -> x end)
|> IO.inspect()
close(input, :input)
close(output)
end
def pad_randoms(output, input) do
1..30
|> Enum.map(fn _ ->
pad_random(output, input)
end)
end
def pad_random(output, input) do
no = Enum.random(0..7)
pad_list()
|> Enum.at(no)
|> then(&pad_led(output, deck1(), &1, led_on()))
ret = midi_in(input)
pag_all_off(output)
(ret == no)
|> IO.inspect()
end
def pag_all_off(output) do
pad_list()
|> Enum.map(fn x ->
pad_led(output, deck1(), x, led_off())
end)
end
def midi_in(input) do
receive do
{^input, []} ->
midi_in(input)
{^input, [{{_, _, 0}, _}]} ->
midi_in(input)
{^input, [{{_, no, 127}, _}]} ->
Process.sleep(500)
no
_ ->
nil
after
500 ->
nil
end
end
end
課題
midi_in(input)
関数のreceive do
で
たまに受信データ[]
が大量に飛んでくる
暫定で再度midi_in(input)
関数を呼び出している
フリーズしてしまう時もある