6
$\begingroup$

I have two lists:

songnotes = {"d5", "d5", "e5", "d5", "d5", "c5", "c5", "a4", "a4", "c5"}
(* timing is the amount of time between the start of the notes *)
timing = {1/4, 1/4, 1/4, 1/4, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2}

And what I want is some sort of visually useful way of me learning how to play the song I just generated. I'm very much an engineer and not a music person (see: this question), so I don't know how to visualize music in written form. The instrument I'm using is the Hapi tone mini drum and only has the following notes:

noteletters = {"c4", "d4", "e4", "g4", "a4", "c5", "d5", "e5"}

I welcome creative responses here because I'm not sure what the best way for me to learn is.

$\endgroup$
4
  • $\begingroup$ You have 10 notes in your song, but 11 entries in your timing list. Should I think of this as: wait 1/4 d5 wait 1/4 d5 wait 1/4 e5 wait 1/4 ... a4 wait 1/2 c5 wait 1/2? $\endgroup$
    – chuy
    Mar 20 '15 at 20:06
  • $\begingroup$ Ah! I don't know how the 11th got in there. It should be equal length lists! $\endgroup$
    – Braains
    Mar 20 '15 at 21:11
  • $\begingroup$ So in theory it's d5 1/4 d5 1/4 ... c5 1/2 $\endgroup$
    – Braains
    Mar 20 '15 at 21:53
  • $\begingroup$ Music types have kind of figured this out already Music theory. Staffs, clefs, ledger lines, notes, time indications. It gives one a remarkably accessible language, grammar, and syntax for doing this sort of thing. Interesting that no one has mentioned it. $\endgroup$
    – Jagra
    Mar 20 '15 at 22:52
8
$\begingroup$

You have a couple of options that might get your creative juice flowing:

1) Make a ListPlot

songnotes = {"d5", "d5", "e5", "d5", "d5", "c5", "c5", "a4", "a4", "c5"};
timing = {1/4, 1/4, 1/4, 1/4, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2};
noteletters = {"c4", "d4", "e4", "g4", "a4", "c5", "d5", "e5"}

Make a substitution rule to help our gathering and sorting. I want each tone to be in a group for coloring purposes.

rule = Thread[noteletters -> Range[8]]
notes = GatherBy[
  SortBy[Last]@(Thread[{Most@FoldList[Plus, 0, timing], 
       songnotes}] /. rule), Last]

Once grouped, use ListPlot:

ListPlot[notes, 
 Ticks -> {Range[0, 4, 1/4], Thread[{Range[8], noteletters}]}, 
 PlotRange -> {{0, 4}, {0, 9}}, PlotStyle -> PointSize[Large], 
 AspectRatio -> 1/5, ImageSize -> Large, 
 GridLines -> {Range[0, 4], Range[8]}, PlotRangeClipping -> False]

enter image description here

2) Use SparseArray and then MatrixPlot:

elements = 
 Thread[Accumulate[timing] -> songnotes] /. rule /. 
  HoldPattern[a_ -> b_] :> {b, 4 a} -> b

set up some color rules:

colors = Thread[Range[1, 8] -> ColorData[3, "ColorList"][[2 ;; 9]]]

MatrixPlot[SparseArray[elements], DataReversed -> True, 
 ColorRules -> {0 -> White}~Join~colors, Mesh -> True, 
 PlotRange -> {All, {1, 16}, All} , 
 FrameTicks -> {Thread[{Range[8], noteletters}], None} ]

enter image description here

$\endgroup$
2
  • $\begingroup$ Wow. That is so cool. Thanks so much!! $\endgroup$
    – Braains
    Mar 20 '15 at 22:52
  • $\begingroup$ I'd thought about improving this by using the actual symbols for the notes, but it seems Mathematica can only show quarter and eighth notes. Oh well. $\endgroup$
    – J. M.'s torpor
    Dec 22 '16 at 3:38
1
$\begingroup$

If you can procure some software for edition:visualisation of MIDI files you can use Mathematica's Export capability:

Sound[Apply [SoundNote ,
Transpose[{
        songnotes = {"d5", "d5", "e5", "d5", "d5", "c5", "c5", "a4", "a4",
           "c5"},
        (*timing is the amount of time between the start of the notes*)

          timing = {1/4, 1/4, 1/4, 1/4, 1/2, 1/2, 1/2, 1/2, 1/2, 1/2} }
       ] , {1}] ]

    Export["mySong.mid", %]
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.