8
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?

ElixirAdvent Calendar 2024

Day 17

DDJ-FLX4のPadをトグルスイッチにする

Posted at

目標

  • Elixirで作る
  • PioneerDjのDDJ-FLX4を使う
  • 各Padの状態を維持する

前提知識

PadのLEDと入力判定

Agentで状態を維持

仕様

  • Padを押すと、オン状態で光る
  • 状態は押すとオンオフ反転する

ソース

defmodule Button do
  @moduledoc """
  Documentation for `Button`.
  """
  use Agent
  @deck1 "97"
  @led_on "7F"
  @led_off "00"

  @pad1 "00"
  @pad2 "01"
  @pad3 "02"
  @pad4 "03"
  @pad5 "04"
  @pad6 "05"
  @pad7 "06"
  @pad8 "07"

  def pad_list, do: [@pad1, @pad2, @pad3, @pad4, @pad5, @pad6, @pad7, @pad8]
  def pad(no), do: pad_list() |> Enum.at(no)

  def start() do
    state = Enum.map(1..8, fn _ -> false end)

    Agent.start_link(fn -> state end, name: __MODULE__)

    {_, input} = PortMidi.open(:input, "DDJ-FLX4 MIDI 1")
    {_, output} = PortMidi.open(:output, "DDJ-FLX4 MIDI 1")
    PortMidi.listen(input, self())

    midi_in(input, output)

    PortMidi.close(:input, input)
    PortMidi.close(:output, output)
  end

  def midi_in(input, output) do
    receive do
      {^input, [{{144, 11, 0}, _}]} ->
        IO.inspect("end")

      {^input, [{{_, no, 127}, _}]} ->
        flg = get_button_state(no)
        set_button_state(no, !flg)

        get_state()
        |> IO.inspect()

        pad_led(output, @deck1, pad(no), led_sw(!flg))

        midi_in(input, output)

      _ ->
        midi_in(input, output)
    end
  end

  def get_button_state(index) do
    get_state()
    |> Enum.at(index)
  end

  def set_button_state(index, flg) do
    get_state()
    |> List.replace_at(index, flg)
    |> set_state()
  end

  def get_state, do: Agent.get(__MODULE__, & &1)
  def set_state(state), do: Agent.update(__MODULE__, fn _ -> state end)

  def pad_led(output, deck, pad, led_sw) do
    [deck, pad, led_sw]
    |> send_midi(output)
  end

  def hex_to_dec(hex), do: String.to_integer(hex, 16)

  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 led_sw(true), do: @led_on
  def led_sw(_), do: @led_off
end

動作動画

8
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
8
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?