Move schedule generation to player.

This commit is contained in:
Pim Kunis 2020-10-11 16:04:56 +02:00
parent 2dac1259b2
commit 95a0712041
3 changed files with 18 additions and 27 deletions

View file

@ -44,7 +44,7 @@ defmodule MIDITools.Event do
@doc """ @doc """
Converts the event to a list of MIDI commands. 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{ def convert(%Note{
channel: channel, channel: channel,
tone: tone, tone: tone,

View file

@ -17,11 +17,16 @@ defmodule MIDITools.Player do
@doc """ @doc """
Set the current schedule and total duration for the MIDI player. 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 The duration makes sure the player plays a (potential) pause after the last
midi command. midi command.
""" """
@spec set_schedule(MIDITools.Schedule.t(), non_neg_integer()) :: :ok @spec set_schedule([MIDITools.Event.t()], non_neg_integer()) :: :ok
def set_schedule(schedule, duration) do def set_schedule(events, duration) do
schedule = convert_events(events)
GenServer.call(__MODULE__, {:set_schedule, schedule, duration}) GenServer.call(__MODULE__, {:set_schedule, schedule, duration})
end end
@ -86,6 +91,7 @@ defmodule MIDITools.Player do
@impl GenServer @impl GenServer
def handle_call({:set_schedule, schedule, duration}, _from, state) do def handle_call({:set_schedule, schedule, duration}, _from, state) do
{:reply, :ok, %{state | schedule: schedule, schedule_left: schedule, duration: duration}} {:reply, :ok, %{state | schedule: schedule, schedule_left: schedule, duration: duration}}
end end
@ -208,4 +214,13 @@ defmodule MIDITools.Player do
{timer, schedule_left} {timer, schedule_left}
end end
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 end

View file

@ -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