9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Elixirでリズムマシンを作る

Last updated at Posted at 2024-12-07

目標

  • MIDI(ソフトシンセ)でリズムマシンを作る
  • 同時発音を攻略する

2年前このコラムで同時発音を諦めていました

midi_synthをdepsに設定

mix.exs
defmodule ElixirSynth.MixProject do
  use Mix.Project

  def project do
    [
      app: :elixir_synth,
      version: "0.1.0",
      elixir: "~> 1.17",
      start_permanent: Mix.env() == :prod,
      deps: deps()
    ]
  end

  # Run "mix help compile.app" to learn about applications.
  def application do
    [
      extra_applications: [:logger]
    ]
  end

  # Run "mix help deps" to learn about dependencies.
  defp deps do
    [
+     {:midi_synth, "~> 0.4.0"}
      # {:dep_from_hexpm, "~> 0.3.0"},
      # {:dep_from_git, git: "https://github.com/elixir-lang/my_dep.git", tag: "0.1.0"}
    ]
  end
end

Task.asyncを使ってパートごと非同期処理をする
計算がめんどくさいから、プロセスを分けてしまう
Task.awaitで各プロセスの同期を取る

defmodule ElixirSynth do
  @moduledoc """
  Documentation for `ElixirSynth`.
  """
  @hi 42
  @bass_drum 36
  @snare 38

  def hello do
    # MIDI 初期化
    {:ok, synth} = MIDISynth.start_link([])

    # 最初だけ同期が取れなかったから、ダミーで1音ならす 理由はわからない
    note(@snare, synth, 1000, 0)
    Process.sleep(100)

    # 8小節鳴らす
    Enum.each(1..8, fn _ ->
      play(synth)
    end)

    :world
  end

  def play(synth) do
    #ハイハット 8分刻み
    hi_task = notes(@hi, 100, 8, synth)

    #バスドラ 4分刻み
    bass_drum_task = notes(@bass_drum, 400, 4, synth)

    #スネア 裏拍
    snare_task = notes(@snare, 400, 2, synth, 600)

    # 小節終わるまで待機
    Task.await(hi_task)
    Task.await(bass_drum_task)
    Task.await(snare_task)
  end

  def notes(note, time, conut, synth, before \\ 0) do
    # 指定した回数音を鳴らす
    # note ノートナンバー
    # time 間隔
    # 鳴らす回数
    # synth MIDIオープンした変数
    # 事前のスリーブ時間
    Task.async(fn ->
      Enum.each(1..conut, fn _ ->
        note(note, synth, time, before)
      end)
    end)
  end

  def note(note, synth, time, before) do
    Process.sleep(before)
    MIDISynth.Keyboard.play(synth, note, 200, 127, 9)
    Process.sleep(time)
  end
end
9
1
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
9
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?