I’m Spike, a coder, Ruby in fact, looking for a creative outlet (which seems to be a common refrain here).
I’m not sure when I first heard about Sonic Pi, but I’ve finally gotten around to playing with it and I’m having fun!
I believe you should alway bring something to share to a party, and to that end, here’s a little bass tab parser I’ve been working on, inspired by this Drum Tab Player.
The parsing is fragile, I don’t read music well nor play the base, so I’m pretty sure my bass map isn’t quite right, and I can’t really make it sounds like a bass yet, but it plays!
BASS_MAP = {
# 0 1 2 3 4 5 6 7 8 9 10 11 12
'G' => [:G1,:Af2,:A2,:Bf2,:B2,:C2,:Df2,:D2,:Ef2,:E2,:F2,:Gf2,:G2],
'D' => [:D1,:Ef1,:E1,:F1,:Gf1,:G1,:Af2,:A2,:Bf2,:B2,:C2,:Df2,:D2],
'A' => [:A1,:Bf1,:B1,:C1,:Df1,:D1,:Ef1,:E1,:F1,:Gf1,:G1,:Ff1,:A2],
'E' => [:E1,:F1,:Fs1,:G1,:Af1,:A1,:Bf1,:B1,:C1,:Df1,:D1,:Ef1,:E1]
}
def tab_to_notes(tab_string)
tab = tab_string.strip.split("\n") # Break up in to lines
.map(&:chars) # Then in to characters
.transpose # Then rotate 90 so we end up with something like:
# [[ "G", "D", "A", "E", ">"]
# [ "—", "—", "3", "—", " "]
# [ "—", "—", "3", "—", " "]
# [ "—", "—", "1", "—", " "]
# ]
# That is, each beat is now it's own array.
strings = tab.shift # Grab string label
tab.shift # Remove space between label and tab, should be smarter
tab.map do |beat|
# Find a number or a "r" rest.
index = beat.find_index {|n| n =~ /[r\d]/}
next if index.nil? # Nothing found, probably just dashes
string = strings[index]
next :r if string == '>' # Rest
fret = beat[index].to_i # Convert the string into a number
BASS_MAP[string][fret] # And return the note
end.compact
end
flashlight_tab = "
G ———————————————————————————————————————————————————————————————————————————————
D ———————————————————————————————————————————————————————————————————————————————
A ——3——3——1——1———————————————————————0——1——2—————————————————————————————————————
E ——————————————3——3——2——2——1—————1——————————————————————————————————————————————
> r .
"
sna_tab = "
G|--------------------------------------------
D|------5-----------------5-------------------
A|-7--7---7--5-------7--7----7--5----5--------
E|-------------8--7----------------8----8--7~-
"
notes = tab_to_notes flashlight_tab
live_loop :bass do
use_synth :piano
notes.each do |note|
play note, sustain: 0.2, amp: 0.3
sleep 0.4
end