5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DDJ-FLX4のPadで「モグラたたきゲーム」を作ろう

Last updated at Posted at 2024-12-07

目標

  • 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)関数を呼び出している
フリーズしてしまう時もある

動作動画

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?