# More elegant function construction for blues loop

Is there a more elegant way to do this:

Sound[With[{li = {{-12, -5, 0}, {-8, -3, 4}, {-5, -13, 2}, {-3, 0, -8},
{-2, -12, -8}, {-3, 0, -8}, {-5, -1, 2}, {-8, -3, -20}},
c = 1.5, v = {0, .4}, b = .2},
Join[
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li)
& /@Range@1,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li + 5)
& /@ Range@1,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li) & /@
Range@2,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li + 5)
& /@ Range@2,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li)
& /@ Range@2,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li + 7)
& /@ Range@1,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li + 5)
& /@ Range@1,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li)
& /@ Range@1,
Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] & /@ (li + 7)
& /@ Range@1] & /@ Range@4]]


?

I went for @eldo 's in the end:

v = {0, 1/2}; c = 5/4; b = 1/4;
li1 = {{-12, -5, 0}, {-8, -3, 4}, {-5, -13, 2}, {-3, 0, -8}};
li2 = {{-12, -5, 0}, {-8, -3, 4}, {-5, -13, 2}, {-3, 0, -8},
{-2, -12, -8}, {-3, 0, -8}, {-5, -1, 2}, {-8, -3, -20}};
tab = Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] &;

Sound[Join[tab /@ (li2) & /@ Range@2, tab /@ (li2 + 5), tab /@ (li2),
tab /@ (li1 + 7), tab /@ (li1 + 5), tab /@ (li2)] & /@ Range@2]


I skipped some tabs

v = {0, .4};
c = 1.5;
b = .2;

tab = Table[SoundNote[#, {p, p + b}/c, "Piano"], {p, v/c}] &;

Sound[
With[{li = {{-12, -5, 0}, {-8, -3, 4}, {-5, -13, 2}, {-3, 0, -8}, {-2, -12, -8}, {-3, 0, -8}, {-5, -1, 2}, {-8, -3, -20}}},
Join[
tab /@ (li) & /@ Range@1,
tab /@ (li + 5) & /@ Range@1,
tab /@ (li + 7) & /@ Range@1] & /@ Range@4]]


Perhaps this, which tries to factor out as much of the repetitive code as possible, while maintaining exactly the structure of the original code, and highlighting that the code really just maps a function over a list of pairs of parameters.

Sound[With[{li = {{-12,-5,0},{-8,-3,4},{-5,-13,2},{-3,0,-8},{-2,-12,-8},{-3,0,-8},
{-5,-1,2},{-8,-3,-20}}, c=1.5, v={0,.4}, b=.2},
f[{li_,ra_}]:=Table[SoundNote[#,{p,p+b}/c,"Piano"],{p,v/c}]& /@ li& /@ Range@ra;
Join @@ Map[f, {{li,1},{li+5,1},{li,2},{li+5,2},{li,2},{li+7,1},{li+5,1},{li,1},
{li+7,1}}]& /@ Range@4]]

• nice - thanks, though I think you forgot to wrap Join ... Range@4] in Sound - great though :) – martin Dec 1 '15 at 6:45
• @martin ACK! You are right. I had removed the Sound[] so that I could could check using == that I was producing exactly the same list as your original code and then didn't put the Sound[] back. Thanks for catching that. Should be fixed now. – Bill Dec 1 '15 at 18:17