2020-10-12 14:17:36 +00:00
|
|
|
# MIDIPlayer
|
2020-10-10 17:36:07 +00:00
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
A MIDI player for Elixir.
|
2020-10-10 17:36:07 +00:00
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
## Prerequisites
|
2020-10-10 17:36:07 +00:00
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
Install FluidSynth to play MIDI commands:
|
|
|
|
|
|
|
|
On Linux:
|
|
|
|
|
|
|
|
```sh
|
|
|
|
sudo apt install libfluidsynth-dev
|
|
|
|
```
|
|
|
|
|
|
|
|
On OSX:
|
|
|
|
|
|
|
|
```sh
|
|
|
|
brew install fluidsynth
|
|
|
|
```
|
|
|
|
|
2020-10-12 21:00:24 +00:00
|
|
|
Clone this repo or put the [Hex dependency](https://hex.pm/packages/midi_player) in your mix.exs:
|
|
|
|
|
|
|
|
```elixir
|
2020-10-14 11:01:21 +00:00
|
|
|
{:midi_player, "~> 0.2.0"}
|
2020-10-12 21:00:24 +00:00
|
|
|
```
|
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
## Examples
|
|
|
|
|
2020-10-12 21:00:24 +00:00
|
|
|
MIDIPlayer takes "events" which for example represent to play a note for a time span.
|
|
|
|
It then converts these events to MIDI commands and schedules them.
|
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
First, let's create some events.
|
|
|
|
This plays a piano sound for the C note for 1 second:
|
|
|
|
|
|
|
|
```elixir
|
2020-10-14 11:01:21 +00:00
|
|
|
iex> piano = MIDIPlayer.Event.note(0, 60, 0, 1000, 127)
|
2020-10-12 19:00:31 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
We can change the instrument to a violin after one second like so:
|
|
|
|
|
|
|
|
```elixir
|
2020-10-14 11:01:21 +00:00
|
|
|
iex> change = MIDIPlayer.Event.change_program(0, 1000, 41)
|
2020-10-12 19:00:31 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
(Note that it could be simpler to use another MIDI channel for another instrument.)
|
|
|
|
|
|
|
|
Finally, play two notes on the violin at the same time:
|
2020-10-10 17:36:07 +00:00
|
|
|
|
|
|
|
```elixir
|
2020-10-14 11:01:21 +00:00
|
|
|
iex> violin1 = MIDIPlayer.Event.note(0, 67, 1000, 3000, 127)
|
|
|
|
iex> violin2 = MIDIPlayer.Event.note(0, 64, 1000, 3000, 127)
|
2020-10-10 17:36:07 +00:00
|
|
|
```
|
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
Now we are ready to play these events.
|
|
|
|
First start the player like so:
|
2020-10-10 17:36:07 +00:00
|
|
|
|
2020-10-12 19:00:31 +00:00
|
|
|
```elixir
|
2020-10-14 13:05:04 +00:00
|
|
|
iex> {:ok, player} = MIDIPlayer.start_link()
|
2020-10-12 19:00:31 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
Then load the events, and play them!
|
|
|
|
|
|
|
|
```elixir
|
2020-10-14 11:01:21 +00:00
|
|
|
iex> MIDIPlayer.generate_schedule(player, [piano, change, violin1, violin2], 3000)
|
|
|
|
iex> MIDIPlayer.play(player)
|
2020-10-12 19:07:28 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
## Thanks
|
|
|
|
|
|
|
|
This project uses [MIDISynth](https://github.com/fhunleth/midi_synth)
|
|
|
|
for generating MIDI commands and operating the FluidSynth synthesizer.
|
|
|
|
It also uses [Timex](https://github.com/bitwalker/timex)
|
|
|
|
for timing related functionality.
|
|
|
|
Inspiration from [Beats](https://github.com/mtrudel/beats).
|