creating midifiles using ruby
I have been experimenting with randomly generated drum patterns lately and found out pretty soon, that a totally random generated pattern isn't exacly what I was after, I wanted a pattern generator where I can specify propabilities for each drum hit to occure. So I wrote a ruby script using midilib that generates midi files containing patterns, which I can then import into bitwig and loop and arrange for my tracks.
Midilib is a nifty little ruby library that allows you to read or write midifiles. For my purpose I used the library to write the files.
the library can be installed using gem
gem install midilib
A midifile contains sequences, sequences contain tracks and tracks contain midi events. These events can be any midi event like noteOn, noteOf, controlChange, programChange, ... For each midiEvent in a track the delta time to the last event is stored.
in midi lib you can specify a time_from_start value and lets midilib recalculate the delta values before saving the track.
So here is a ruby script that generates a hihat pattern (channel 1, midi note 44 in my kit), where the notes are placed on a 16th grid with a random chance between 20% and 50%.
require 'midilib/sequence'
require 'midilib/consts'
include MIDI
seq = Sequence.new()
track = Track.new(seq)
seq.tracks << track
track.events << Tempo.new(Tempo.bpm_to_mpq(110))
track.events << MetaEvent.new(META_SEQ_NAME, 'Test Pattern')
track = Track.new(seq)
seq.tracks << track
track.name = 'Loop1'
s = 0
l = seq.note_to_delta('16th')
e = Random.rand(0.2..0.5)
16.times do
if ( Random.rand < e ) then
on = NoteOn.new(0,44,127,0)
on.time_from_start = s
off = NoteOff.new(0,44,127,0)
off.time_from_start = s + l
track.events << on
track.events << off
end
s += l
end
track.recalc_delta_from_times
File.open('pattern3.mid', 'wb') { |file| seq.write(file) }
See also:
Calculating Euclidean Rhythmns using the Bresenham Algorithm
Semimodular meets SonicPI
launchpad mini to play push like scales using puredata
Midified Monotron first track