# YAMI (Yet Another MIDI Importer)

**URL:** <https://in-thread.sonic-pi.net/t/yami-yet-another-midi-importer/2436>\
**Category:** Creations & Ideas\
**Created:** [May 31, 2019, 3:54pm UTC](https://in-thread.sonic-pi.net/t/yami-yet-another-midi-importer/2436 "2019-05-31T15:54:41Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![perpetual\_monday](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/perpetual_monday/32/955_2.png) [@perpetual\_monday](https://in-thread.sonic-pi.net/u/perpetual_monday)\
**Post date:** [May 31, 2019, 3:54pm UTC](https://in-thread.sonic-pi.net/t/yami-yet-another-midi-importer/2436/1 "2019-05-31T15:54:41Z")

</div>

Last night I started hacking away at my own tool for converting MIDI files into Sonic Pi code. I’ve looked at examples in the forum and the nice write-ups by @robin.newman, which I will continue learning from. For my specific needs I have a bunch of MIDI drum/keyboard/bass loop files that I’d like to load in and mix together. These will typically only constitute a few to several seconds of performance duration and my ideal is to convert directories of these loops into Sonic Pi code.

I’m using a Python package called [Mido](https://mido.readthedocs.io/en/latest/index.html) to help with parsing the messages and calculating time to beat conversions. My first pass dumpster fire is [here](https://gist.github.com/unbracketed/17b46c575463fb5dae2d5a0d58083264). Currently the code takes a file I have and splits each drum type into a different loop. The output for my sample file looks like (disclaimer: the sample names were post-edited by hand, but future versions will map those in from an initial config):

```ruby
use_bpm 98

live_loop :bass_drum_1_loop do
  sleep 0.0
  
  sample :drum_bass_hard
  sleep 1.5
  
  sample :drum_bass_hard
  sleep 0.4999999999999998
  
  sample :drum_bass_hard
  sleep 1.9999999999999998
  
  sample :drum_bass_hard
  sleep 1.4999999999999996
  
  sample :drum_bass_hard
  sleep 0.5000000000000009
  
  sample :drum_bass_hard
  sync :loop_window
  
end

live_loop :acoustic_snare_loop do
  sleep 3.0
  
  sample :drum_snare_hard
  sleep 3.5
  
  sample :drum_snare_hard
  sleep 0.9999999999999991
  
  sample :drum_snare_hard
  sync :loop_window
  
end

live_loop :high_floor_tom_loop do
  sleep 7.499999999999999
  
  sample :drum_tom_lo_hard
  sync :loop_window
  
end

live_loop :loop_window do
  8.times do
    sleep 1
  end
end

```

---

<div class="post-metadata">

**Author:** ![perpetual\_monday](https://dub1.discourse-cdn.com/flex017/user_avatar/in-thread.sonic-pi.net/perpetual_monday/32/955_2.png) [@perpetual\_monday](https://in-thread.sonic-pi.net/u/perpetual_monday)\
**Post date:** [May 31, 2019, 4:07pm UTC](https://in-thread.sonic-pi.net/t/yami-yet-another-midi-importer/2436/2 "2019-05-31T16:07:27Z")

</div>

In future iterations I plan to get away from unrolling the timings into `sample / sleep` statements. I’d rather have more compact files that are just data structures with all the timings and data that I can then run with a helper function in a loop (pseudocode):

```ruby
# Sonic Pi converted MIDI file patterns
Akron_Grv_1 = [...]
Akron_Grv_2 = [...]
Akron_Fill_1 = [...]

set drummer_pattern 'Akron_Grv_2'

define playPattern |name| do
  # iterate through pattern, sleeping and sampling at appropriate times
end

live_loop :drummer do
  playPattern(get['drummer_pattern'])
end

```
