creating midifiles using ruby

Nikolaus Gradwohl2018-03-26T07:21:37+00:00

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.

arpeggio

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) }
read more ...