I would like to create a simple program that will generate MIDI files. No, I don't want to use Haskore, because it is kinda overkill for this project. I think something like this library will be sufficient.
What I want to be able to do:
It is as simple as that, I bet it is not hard, but I cannot find any good example how to do it.
Please provide a basic example or point out where I can find information regarding creation of MIDI files in Haskell.
Note: I'm not asking you about good library to do it, I'm asking you how to do it in Haskell (with any library that you deem good for using in example).
OK, I'm not sure that it was a good question, but I cannot wait anymore, so here is how to write some MIDI using Haskell. I should note that the topic is barely documented except for some package descriptions that look rather cryptic.
Most minimalistic package which suits our needs is HCodecs and it seems to be updated regularly. We're interested in module Codec.Midi.
In this library events are expected to be represented as tuples:
(time-offset, message)
Where time-offset
is elapsed time in ticks (see below how to set number of ticks per beat) between the last event and new one. message
must be of type Message
, full list of constructors can be found here. These constructors correspond to all basic MIDI events.
Track is a list of events. So we can write something very simplistic now:
track0 = [(0, NoteOn 0 60 80),
(24, NoteOff 0 60 0),
(0, TrackEnd)]
It is one note (60 = middle C), we have used here events NoteOn
and NoteOff
(it is the same as NoteOn
of 0
velocity, so in practice people tend to use only NoteOn
). For more information about what one can do here Google about MIDI format!
Let's create one more track containing E:
track1 = [(0, NoteOn 0 64 80),
(24, NoteOn 0 64 0),
(0, TrackEnd)]
Great! It's time to put the data into MIDI container.
Let's create object that represents entire MIDI file. We will use constructor of Midi
datatype.
myMidi = Midi { fileType = MultiTrack,
timeDiv = TicksPerBeat 24,
tracks = [track0, track1] }
That's it! timeDiv
defines quantization of the track, if we have 24
ticks per beat, our notes will sound exactly for one beat (sure, you can add some events to set tempo and stuff, try it!).
To save a Midi
we should use exportFile
(click the link for more information... OK, just kidding there is no even a one-line description):
exportFile "my-midi.mid" myMidi
Done.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With