Skip to content

Instantly share code, notes, and snippets.

@jarmitage
Created September 29, 2017 03:20
Show Gist options
  • Save jarmitage/53e76b9057f99b3f94c1361267ab8a13 to your computer and use it in GitHub Desktop.
Save jarmitage/53e76b9057f99b3f94c1361267ab8a13 to your computer and use it in GitHub Desktop.
Guitar tab -> TidalCycles
-- (untested!)
{-
Parsing guitar tabs into Tidal code. Because.
Tab template for a six string guitar in standard tuning:
e|-------------|
B|-------------|
G|-------------|
D|-------------|
A|-------------|
E|-------------|
First we need the note values for each string as specified on the left. We will use Middle C as the reference point:
`n "c"` is `n "c5"` is `n 0` is `midinote 60`
On a guitar in standard tuning, middle C is 8th fret on low E or 3rd fret on A, so:
Guit n midinote Name
-------------------------
e| 16 76 e6
B| 11 71 b5
G| 7 67 g5
D| 2 62 d5
A| -3 57 a4
E| -8 52 e4
One way of specifying this would be:
-}
let ge p = (|+| n "e6") $ n p -- 16
gB p = (|+| n "b5") $ n p -- 11
gG p = (|+| n "g5") $ n p -- 7
gD p = (|+| n "d5") $ n p -- 2
gA p = (|+| n "a4") $ n p -- -3
gE p = (|+| n "e4") $ n p -- -8
{-
We need two things from the guitar tab: notes and timing info. Notes are pretty easy:
https://tabs.ultimate-guitar.com/g/guns_n_roses/sweet_child_o_mine_intro_tab.htm
e|---------------14----13-----|
B|------14--------------------|
G|---------13-11----13----13--|
D|---11-----------------------|
A|----------------------------|
E|----------------------------|
To create a Tidal pattern from this you can iterate string by string:
-}
d1 $ stack [
ge "~ ~ ~ ~ 14 ~ 13 ~",
gB "~ 14 ~ ~ ~ ~ ~ ~",
gG "~ ~ 13 11 ~ 13 ~ 13",
gD "11 ~ ~ ~ ~ ~ ~ ~",
] # s "superpiano"
{-
This can be simplified by adding the string note offsets:
ge + 16 = "~ ~ ~ ~ 30 ~ 29 ~,
gB + 11 = "~ 25 ~ ~ ~ ~ ~ ~,
gG + 7 = "~ ~ 20 18 ~ 20 ~ 20,
gD + 2 = "13 ~ ~ ~ ~ ~ ~ ~",
And then flattening these four patterns into one:
-}
d1 $ n "13 25 20 18 30 20 29 20" # s "superpiano"
{-
But how did we get the timing information? Guitar tab is quite bad for authoring / reading precise timings, and often this is implicitly left to the reader/player. However in this case if we go back to our tab:
e|---------------14----13-----|
B|------14--------------------|
G|---------13-11----13----13--|
D|---11-----------------------|
A|----------------------------|
E|----------------------------|
We know the first note happens at the start of the bar, we can see that there is one `-` between each note, and there is also one unneccessary extra `-` at the end. So we can clean this up a bit to:
e|------------14----13----|
B|---14-------------------|
G|------13-11----13----13-|
D|11----------------------|
A|------------------------|
E|------------------------|
We have eight notes in total that are evenly spread across one bar, so each note is one quaver long.
-}
{-
Let's look at a polyphonic piece, with multiple bars and a hammer-on:
https://tabs.ultimate-guitar.com/b/ben_harper/walk_away_ver3_tab.htm
e|------3---3--|------3---3--|------3---3--|------3---3--|
B|------3---3--|------3---3--|------3---3--|------3---3--|
G|------0---0--|------0---0--|------0---0--|------0---0--|
D|-------------|-------------|-------------|-------------|
A|-------------|-------------|-------------|-------------|
E|-3-3---------|-2-2---------|-0-0---------|--0^2-2------|
If you listen to the track (https://www.youtube.com/watch?v=CB_wZ_0s7mc) you can tell that the basic rhythm should actually be.
e|-----3--3--|-----3--3--|-----3--3--|------3--3--|
B|-----3--3--|-----3--3--|-----3--3--|------3--3--|
G|-----0--0--|-----0--0--|-----0--0--|------0--0--|
D|-----------|-----------|-----------|------------|
A|-----------|-----------|-----------|------------|
E|-3-3-------|-2-2-------|-0-0-------|--0^2-2-----|
And here we hit a limitation with tab, as the last bar now has an incorrect number of `-` due to the hammer-on. But anyway.
-}
d1 $ stack [
ge "[~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3]",
gB "[~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3]",
gG "[~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0]",
gD "[~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~]",
gA "[~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~] [~ ~ ~ ~ ~ ~ ~ ~]",
gE "[3 ~ 3 ~ ~ ~ ~ ~] [2 ~ 2 ~ ~ ~ ~ ~] [0 ~ 0 ~ ~ ~ ~ ~] [[[0 2] ~ 2] ~ ~ ~ ~ ~]",
] # s "superpiano"
d1 $ stack [
ge "[~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3]",
gB "[~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3] [~ ~ ~ ~ 3 ~ ~ 3]",
gG "[~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0] [~ ~ ~ ~ 0 ~ ~ 0]",
gE "[3 ~ 3 ~ ~ ~ ~ ~] [2 ~ 2 ~ ~ ~ ~ ~] [0 ~ 0 ~ ~ ~ ~ ~] [[[0 2] ~ 2] ~ ~ ~ ~ ~]",
] # s "superpiano"
d1 $ stack [
ge "[~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]]",
gB "[~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]]",
gG "[~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]]",
gE "[[3 3] ~ ] [[2 2] ~ ] [[0 0] ~ ] [[[0 2] 2] ~ ]",
] # s "superpiano"
d1 $ stack [
ge "[~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]]",
gB "[~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]] [~ [3 ~ ~ 3]]",
gG "[~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]] [~ [0 ~ ~ 0]]",
gE "[[3 3] ~ ] [[2 2] ~ ] [[0 0] ~ ] [[[0 2] 2] ~ ]",
] # s "superpiano"
{-
In this case you can see that the top three strings do not change, so when we flatten this it would make sense to group those.
Guit n midinote Name
-------------------------
e| 16 76 e6
B| 11 71 b5
G| 7 67 g5
D| 2 62 d5
A| -3 57 a4
E| -8 52 e4
-}
d1 $ stack [
n "[~ [[7, 14, 19] ~ ~ [7, 14, 19]]]*4", -- top strings
n "[[[-5 -5] ~ ] [[-6 -6] ~ ] [[-8 -8] ~ ] [[[-8 -6] -6] ~ ]]" -- bottom string
] # superpiano
-- or in one line
d1 $ n "[[[-5 -5] ~ ] [[-6 -6] ~ ] [[-8 -8] ~ ] [[[-8 -6] -6] ~ ]], [~ [[7, 14, 19] ~ ~ [7, 14, 19]]]*4" # superpiano
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment