From 95a0712041e823037754cbbcb1dd61983845b5a1 Mon Sep 17 00:00:00 2001 From: Pim Kunis Date: Sun, 11 Oct 2020 16:04:56 +0200 Subject: [PATCH] Move schedule generation to player. --- lib/midi_tools/event.ex | 2 +- lib/midi_tools/player.ex | 19 +++++++++++++++++-- lib/midi_tools/schedule.ex | 24 ------------------------ 3 files changed, 18 insertions(+), 27 deletions(-) delete mode 100644 lib/midi_tools/schedule.ex diff --git a/lib/midi_tools/event.ex b/lib/midi_tools/event.ex index e11aeb1..8d7d89c 100644 --- a/lib/midi_tools/event.ex +++ b/lib/midi_tools/event.ex @@ -44,7 +44,7 @@ defmodule MIDITools.Event do @doc """ Converts the event to a list of MIDI commands. """ - @spec convert(t()) :: MIDITools.Schedule.t() + @spec convert(t()) :: [{non_neg_integer(), binary()}] def convert(%Note{ channel: channel, tone: tone, diff --git a/lib/midi_tools/player.ex b/lib/midi_tools/player.ex index 1ff5b34..f149dfd 100644 --- a/lib/midi_tools/player.ex +++ b/lib/midi_tools/player.ex @@ -17,11 +17,16 @@ defmodule MIDITools.Player do @doc """ Set the current schedule and total duration for the MIDI player. + + The list of events is internally converted to MIDI commands. + If multiple events are scheduled on the same time, + then they are executed in the same order as in the list. The duration makes sure the player plays a (potential) pause after the last midi command. """ - @spec set_schedule(MIDITools.Schedule.t(), non_neg_integer()) :: :ok - def set_schedule(schedule, duration) do + @spec set_schedule([MIDITools.Event.t()], non_neg_integer()) :: :ok + def set_schedule(events, duration) do + schedule = convert_events(events) GenServer.call(__MODULE__, {:set_schedule, schedule, duration}) end @@ -86,6 +91,7 @@ defmodule MIDITools.Player do @impl GenServer def handle_call({:set_schedule, schedule, duration}, _from, state) do + {:reply, :ok, %{state | schedule: schedule, schedule_left: schedule, duration: duration}} end @@ -208,4 +214,13 @@ defmodule MIDITools.Player do {timer, schedule_left} end end + + defp convert_events(events) do + events + |> Enum.flat_map(&MIDITools.Event.convert/1) + |> Enum.reduce(%{}, fn {time, midi}, acc -> + Map.update(acc, time, midi, &<<&1::binary, midi::binary>>) + end) + |> Enum.sort() + end end diff --git a/lib/midi_tools/schedule.ex b/lib/midi_tools/schedule.ex deleted file mode 100644 index e98f75a..0000000 --- a/lib/midi_tools/schedule.ex +++ /dev/null @@ -1,24 +0,0 @@ -defmodule MIDITools.Schedule do - @moduledoc """ - Functions for using a MIDI schedule. - """ - - @typedoc """ - A list of tuples which indicate that the MIDI binary should play at the given time. - """ - @type t :: [{non_neg_integer(), binary()}] - - @doc """ - Convert a list of events to MIDI schedule. - See `MIDITools.Event` for creating these events. - """ - @spec convert_events([MIDITools.Event.t()]) :: t() - def convert_events(events) do - events - |> Enum.flat_map(&MIDITools.Event.convert/1) - |> Enum.reduce(%{}, fn {time, midi}, acc -> - Map.update(acc, time, midi, &<<&1::binary, midi::binary>>) - end) - |> Enum.sort() - end -end