Skip to content

fhunleth/midi_synth

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MIDISynth

CircleCI Hex.pm Hex.pm Hex.pm github.com

Play music in Elixir.

Trying it out

First, install FluidSynth.

On Linux:

sudo apt install libfluidsynth-dev

On MacOS:

brew install fluidsynth pkg-config

Next, either clone this library or pull it in as a dependency to your Elixir project. The following is an example of the dependency for your mix.exs:

{:midi_synth, "~> 0.4.0"}

Fetch dependencies and build as you normally would. The first build will download the FluidR3_GM.sf2 soundfont file. This is a Creative Commons-licensed data file that contains all of the General MIDI instruments. It is a good place to start, but can be changed later on.

IMPORTANT: If midi_synth has a compiler error on MacOS, it is likely that it is due to an error in a pkg-config file referred to by fluidsynth.pc. To fix, edit /opt/homebrew/lib/pkgconfig/fluidsynth.pc and remove the word "readline".

Try it out using IEx

Start IEx by running iex -S mix from a shell prompt.

MIDISynth is a GenServer and must be started first. The library comes with with helpers to make playing simple things easy. For more complicated uses, you'll want to build on this library.

OK, let's play a note. Notes are numbered sequentially. Middle C is note 60. Here's how to play middle C for 100 ms.

iex> {:ok, synth} = MIDISynth.start_link([])
{:ok, #PID<0.226.0>}
iex> MIDISynth.Keyboard.play(synth, 60, 100)

You can play the same note with a different velocity. The velocities range from 1 to 127. Here's how to play middle C for 100 ms with velocity mezzo-forte: 80.

iex> MIDISynth.Keyboard.play(synth, 60, 100, 80)

If you don't like the piano, try switching the instrument to something else. For example, trumpets (General MIDI instrument 57) are nice:

iex> MIDISynth.Keyboard.change_program(synth, 57)
iex> MIDISynth.Keyboard.play(synth, 60, 500)

Percussion instruments can be played only through MIDI channel 9. For example, this is how to play a cowbell sound:

iex> MIDISynth.Keyboard.play(synth, 56, 0, 127, 9)

The real value of this library is the ability to send raw MIDI messages to the FluidSynth library. The Elixir code barely scratches the surface of what's possible. If you're comfortable with raw MIDI commands, try this out:

iex> MIDISynth.midi(synth, <<0x90, 60, 127>>)
iex> MIDISynth.midi(synth, <<0x80, 60, 127>>)

See MIDISynth.Command for help with encoding messages, and please feel free to add more.

License

The Elixir and C code are covered by the Apache 2 License.