2020-10-11 09:55:01 +00:00
|
|
|
defmodule MIDITools.Event do
|
2020-10-11 11:40:12 +00:00
|
|
|
@moduledoc """
|
|
|
|
Several musical events which can be converted to MIDI commands.
|
|
|
|
All timings are in milliseconds.
|
|
|
|
"""
|
|
|
|
|
2020-10-11 09:55:01 +00:00
|
|
|
defmodule Note do
|
2020-10-11 11:40:12 +00:00
|
|
|
@moduledoc """
|
|
|
|
An event which plays the given tone for the given timespan.
|
|
|
|
"""
|
|
|
|
|
2020-10-11 09:55:01 +00:00
|
|
|
defstruct channel: 0, tone: 0, start_time: 0, end_time: 0, velocity: 0
|
|
|
|
|
2020-10-11 11:40:12 +00:00
|
|
|
@spec new(MIDISynth.Command.channel(), non_neg_integer(), non_neg_integer(), non_neg_integer(), MIDISynth.Command.velocity()) :: %Note{}
|
|
|
|
def new(channel, tone, start_time, end_time, velocity) when start_time >= 0 and end_time > start_time do
|
2020-10-11 09:55:01 +00:00
|
|
|
%__MODULE__{
|
|
|
|
channel: channel,
|
|
|
|
tone: tone,
|
|
|
|
start_time: start_time,
|
|
|
|
end_time: end_time,
|
|
|
|
velocity: velocity
|
|
|
|
}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-11 10:27:49 +00:00
|
|
|
defmodule ChangeProgram do
|
2020-10-11 11:40:12 +00:00
|
|
|
@moduledoc """
|
|
|
|
An event which changes the current program of the given channel.
|
|
|
|
"""
|
|
|
|
|
2020-10-11 10:27:49 +00:00
|
|
|
defstruct channel: 0, time: 0, program: 0
|
|
|
|
|
2020-10-11 11:40:12 +00:00
|
|
|
@spec new(MIDISynth.Command.channel(), non_neg_integer(), non_neg_integer()) :: %ChangeProgram{}
|
2020-10-11 10:27:49 +00:00
|
|
|
def new(channel, time, program) do
|
|
|
|
%__MODULE__{channel: channel, time: time, program: program}
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2020-10-11 11:40:12 +00:00
|
|
|
@typedoc """
|
|
|
|
A musical event.
|
|
|
|
"""
|
|
|
|
@type t :: %Note{} | %ChangeProgram{}
|
|
|
|
|
|
|
|
@doc """
|
|
|
|
Converts the event to a list of MIDI commands.
|
|
|
|
"""
|
2020-10-11 14:04:56 +00:00
|
|
|
@spec convert(t()) :: [{non_neg_integer(), binary()}]
|
2020-10-11 09:55:01 +00:00
|
|
|
def convert(%Note{
|
|
|
|
channel: channel,
|
|
|
|
tone: tone,
|
|
|
|
start_time: start_time,
|
|
|
|
end_time: end_time,
|
|
|
|
velocity: velocity
|
|
|
|
}) do
|
|
|
|
note_on = MIDISynth.Command.note_on(channel, tone, velocity)
|
|
|
|
note_off = MIDISynth.Command.note_off(channel, tone)
|
|
|
|
[{start_time, note_on}, {end_time, note_off}]
|
|
|
|
end
|
2020-10-11 10:27:49 +00:00
|
|
|
|
|
|
|
def convert(%ChangeProgram{channel: channel, time: time, program: program}) do
|
|
|
|
change_program = MIDISynth.Command.change_program(channel, program)
|
|
|
|
|
|
|
|
[{time, change_program}]
|
|
|
|
end
|
2020-10-11 09:55:01 +00:00
|
|
|
end
|