Message Boards Message Boards

3
|
4641 Views
|
0 Replies
|
3 Total Likes
View groups...
Share
Share this post:

Piano Lesson

Posted 9 years ago

The well-temperated keyboard has two mirror symmetric points: D4 and GSharp4. (If one identifies A0 with A7 there are more symmetry points, of course.) The pianist Marc-André Hamelin advises to play with both hands in mirror symmetry with respect to the one or the other symmetry point. This can be done in principle with any piano piece for two hands: Play the right hand as written and the left hand in mirror symmetry or vice versa. That lets the brain work, but is not straightforward because there is no sheet to read from.

So let's produce some sheets with a simple finger exercise. The 5 fingers of each hand play the same pitches in mirror symmetry, but possibly with a different sequence of the fingers. As usual (J. Brahms, 51 Übungen für Klavier) the phrase is repeated up and down.

Remove[pitch, pianoLesson]
pitch[l_List, o_Integer, oo_Integer] := 
 Block[{d = {{"a0", 0, 1}, {"as0", 1, -1}, {"b0", 0, 0},
      {"c1", 0, 1}, {"cs1", 1, -1}, {"d1", 0, 1}, {"ds1", 
       1, -1}, {"e1", 0, 0},
      {"f1", 0, 1}, {"fs1", 1, -1}, {"g1", 0, 1}, {"gs1", 
       1, -1}, {"a1", 0, 1}, {"as1", 1, -1}, {"b1", 0, 0},
      {"c2", 0, 1}, {"cs2", 1, -1}, {"d2", 0, 1}, {"ds2", 
       1, -1}, {"e2", 0, 0},
      {"f2", 0, 1}, {"fs2", 1, -1}, {"g2", 0, 1}, {"gs2", 
       1, -1}, {"a2", 0, 1}, {"as2", 1, -1}, {"b2", 0, 0},
      {"c3", 0, 1}, {"cs3", 1, -1}, {"d3", 0, 1}, {"ds3", 
       1, -1}, {"e3", 0, 0},
      {"f3", 0, 1}, {"fs3", 1, -1}, {"g3", 0, 1}, {"gs3", 
       1, -1}, {"a3", 0, 1}, {"as3", 1, -1}, {"b3", 0, 0},
      {"c4", 0, 1}, {"cs4", 1, -1}, {"d4", 0, 1}, {"ds4", 
       1, -1}, {"e4", 0, 0},
      {"f4", 0, 1}, {"fs4", 1, -1}, {"g4", 0, 1}, {"gs4", 
       1, -1}, {"a4", 0, 1}, {"as4", 1, -1}, {"b4", 0, 0},
      {"c5", 0, 1}, {"cs5", 1, -1}, {"d5", 0, 1}, {"ds5", 
       1, -1}, {"e5", 0, 0},
      {"f5", 0, 1}, {"fs5", 1, -1}, {"g5", 0, 1}, {"gs5", 
       1, -1}, {"a5", 0, 1}, {"as5", 1, -1}, {"b5", 0, 0},
      {"c6", 0, 1}, {"cs6", 1, -1}, {"d6", 0, 1}, {"ds6", 
       1, -1}, {"e6", 0, 0},
      {"f6", 0, 1}, {"fs6", 1, -1}, {"g6", 0, 1}, {"gs6", 
       1, -1}, {"a6", 0, 1}, {"as6", 1, -1}, {"b6", 0, 0},
      {"c7", 0, 1}, {"cs7", 1, -1}, {"d7", 0, 1}, {"ds7", 
       1, -1}, {"e7", 0, 0},
      {"f7", 0, 1}, {"fs1", 1, -1}, {"g7", 0, 1}, {"gs7", 
       1, -1}, {"a7", 0, 1}, {"as7", 1, -1}, {"b7", 0, 0},
      {"c8", 0, 1},
      }, rS},
   If[Length[l] == 0,
    rS = d[[o, 1]], (* else *)
    If[d[[o, 2]] == 1 (* the current note has a sharp *),
     If[IntersectingQ[l, {o}],
      If[Max[Flatten[Position[l, o]]] < 
        Max[Flatten[Position[l, o + d[[o, 3]]]]],
       rS = d[[o, 1]],(* else: do not repeat the sharp *)
       rS = d[[o + d[[o, 3]], 1]]
       ],(* else *)
      rS = d[[o, 1]]
      ], (* else *)
     If [IntersectingQ[l, {o + d[[o, 3]]}] && d[[o, 3]] == 1,
      If[Max[Flatten[Position[l, o + d[[o, 3]]]]] < 
        Max[Flatten[Position[l, o]]],
       rS = d[[o, 1]],(* else: go natural *)
       rS = 
        StringJoin[{StringTake[d[[o, 1]], 1], "n", 
          StringTake[d[[o, 1]], -1]}]
       ],(* else *)
      rS = d[[o, 1]]
      ]
     ]
    ];
   If[oo == 3,
    StringJoin[{StringTake[rS, StringLength[rS] - 1], "2", 
      StringTake[rS, -1], "x5"}], (* else *)
    rS
    ]
   ] /; 1 <= o <= 88 && 1 <= oo <= 3 && VectorQ[l, IntegerQ]
pianoLesson[sym_String (* symmetry point: d or gs *),
  notes_List (* the notes (half-tones) to be played symmetrical *),
  step_Integer(* repeat n half-tone steps higher *),
  rep_Integer (* how much repetitions upwards *),
  fLeft_List(* finger permutation left hand *),
  fRight_List(* finger permutation right hand *) ] := Module[{
    (* costumize that *)
    musDir = FileNameJoin[{NotebookDirectory[], "..", "Abt_M"}],
    baP, fN, fNpmx, fNpdf, spmx, fL, fR, pL, pR, npag, nsys, o},
   (* check the technology stack *)
   If[! DirectoryQ[musDir],
    Print["musDir \"", musDir, "\" is not a directory. Bye."];
        Return[$Failed]
    ];
   (* get the file name *)
   fN = FileNameTake /@ FileNames["finger_*.pmx", {musDir}];
   If[Length[fN] == 0,
    fN = 1, (* else *)
    fN = Max[
       ToExpression /@ 
        Flatten[Select[StringSplit[#, {"finger_", ".pmx"}] & /@ fN, 
          NumberQ[ToExpression[#[[1]]]] &]]] + 1
    ];
   fNpmx = FileNameJoin[{musDir, "finger_" <> ToString[fN] <> ".pmx"}];
   fNpdf = FileNameJoin[{musDir, "finger_" <> ToString[fN] <> ".pdf"}];
   Print["Exercise ", fN, " appears in \"", fNpmx, "\"" ];
   (* get the base point *)
   baP = If[sym == "d", 42, 48];
   (* fingering *)
   fL = Sort[notes][[#]] & /@ fLeft;
   fR = Sort[notes][[#]] & /@ fRight;
   (* go up (R) and down (L) *)
   pL = Select[FoldList[Plus, baP - fL, ConstantArray[-step, {rep}]], 
     Max[#] < 88 &];
   pR = Select[FoldList[Plus, baP + fR, ConstantArray[step, {rep}]], 
     Min[#] > 1 &];
   (* the shortest rules (not correct because 88 is even and baP is \
not the median) *)
   If[Length[pL] > Length[pR],
    pL = Take[pL, Length[pR]], (* else *)
    If[Length[pR] > Length[pL],
     pR = Take[pR, Length[pL]]
     ]
    ];
   (* go down (R) and up (L) again *)
   pL = Join[pL, Reverse[Most[pL]]];
   pR = Join[pR, Reverse[Most[pR]]];
   (* Print["pR: ",pR]; *)
   If[Length[pL] != Length[pR],
    Print["An internal error occured!"];
    Return[$Failed]
    ];
   (* compute npages and nsystems *)
   nsys = Ceiling[Length[pL]/(2 3)];
   npag = Ceiling[nsys/5];
   (* write the file header *)
   spmx = OpenWrite[fNpmx];
   WriteLine[spmx, "%------------------------%"]; 
   WriteLine[spmx, "%"]; WriteLine[spmx, "% " <> FileNameTake[fNpmx]];
    WriteLine[spmx, "%"]; 
   WriteLine[spmx, "% mirror symmetric exercise"]; 
   WriteLine[spmx, "%"]; 
   WriteLine[spmx, "%------------------------%"]; 
   WriteLine[spmx, "%"]; WriteLine[spmx, "---"];
   WriteLine[spmx, "\\font\\tit=cmcsc10 scaled\\magstep 5"];
   WriteLine[spmx, "\\font\\dat=cmr12"];
   WriteLine[spmx, 
    "\\def\\comp{\\rightline{\\medtype pianoLesson.nb}}"]; 
   WriteLine[spmx, 
    "\\def\\data{\\rightline{\\medtype " <> DateString[DateObject[]] <>
      "}}"]; WriteLine[spmx, "---"]; 
   WriteLine[spmx, "2 1 4 4 4 4 0 0"];
   WriteLine[spmx, "% npages nsystems musicsize fracindent"]; 
   WriteLine[spmx, 
    ToString[npag] <> " " <> ToString[nsys] <> " 20 0.07"]; 
   WriteLine[spmx, "% finger_<n>.pmx"]; 
   WriteLine[spmx, ToString[fN] <> "."]; WriteLine[spmx, "bt"]; 
   WriteLine[spmx, "." <> $PathnameSeparator];
   WriteLine[spmx, "Abe"]; 
   WriteLine[spmx, 
    "\\\\def\\writebarno{\\ifnum\\barno>1\\lrlap{\\oldstyle\\the\\\
barno\\barnoadd}\\fi}%\\"]; 
   WriteLine[spmx, "\\\\def\\shiftbarno{0\\Interligne}\\"];
   WriteLine[spmx, "Tt"];
   WriteLine[spmx, "{\\tit Exercise}"];
   WriteLine[spmx, "Tc"];
   WriteLine[spmx, "\\vbox{\\comp\\data}"];
   Close[spmx];
   (* write the notes bar-wise *)
   spmx = OpenAppend[fNpmx];
   For[o = 1, o <= Length[pL] - 1, o = o + 2,
    WriteLine[spmx, "% bar " <> ToString[Ceiling[o/2]]];
    (* do not repeat accidentals in a bar; 
    add the natural accidental where needed *)
    WriteLine[spmx, StringJoin[{pitch[{}, pL[[o, 1]], 3], " ", 
       pitch[pL[[o, 1 ;; 1]], pL[[o, 2]], 1], " ",
       pitch[pL[[o, 1 ;; 2]], pL[[o, 3]], 1], " ",
       pitch[pL[[o, 1 ;; 3]], pL[[o, 4]], 1], " ",
       pitch[pL[[o, 1 ;; 4]], pL[[o, 5]], 1], " ",
       pitch[pL[[o]], pL[[o + 1, 1]], 3], " ", 
       pitch[Join[pL[[o]], pL[[o + 1, 1 ;; 1]]], pL[[o + 1, 2]], 1], 
       " ",
       pitch[Join[pL[[o]], pL[[o + 1, 1 ;; 2]]], pL[[o + 1, 3]], 1], 
       " ",
       pitch[Join[pL[[o]], pL[[o + 1, 1 ;; 3]]], pL[[o + 1, 4]], 1], 
       " ",
       pitch[Join[pL[[o]], pL[[o + 1, 1 ;; 4]]], pL[[o + 1, 5]], 1], 
       " /"}]
     ];
    WriteLine[spmx, StringJoin[{pitch[{}, pR[[o, 1]], 3], " ",
       pitch[pR[[o, 1 ;; 1]], pR[[o, 2]], 1], " ",
       pitch[pR[[o, 1 ;; 2]], pR[[o, 3]], 1], " ",
       pitch[pR[[o, 1 ;; 3]], pR[[o, 4]], 1], " ",
       pitch[pR[[o, 1 ;; 4]], pR[[o, 5]], 1], " ",
       pitch[pR[[o]], pR[[o + 1, 1]], 3], " ", 
       pitch[Join[pR[[o]], pR[[o + 1, 1 ;; 1]]], pR[[o + 1, 2]], 1], 
       " ",
       pitch[Join[pR[[o]], pR[[o + 1, 1 ;; 2]]], pR[[o + 1, 3]], 1], 
       " ",
       pitch[Join[pR[[o]], pR[[o + 1, 1 ;; 3]]], pR[[o + 1, 4]], 1], 
       " ",
       pitch[Join[pR[[o]], pR[[o + 1, 1 ;; 4]]], pR[[o + 1, 5]], 1], 
       " /"}] 
     ]
    ];
   If [OddQ[Length[pL]],
    o = Length[pL];
    WriteLine[spmx, "% bar " <> ToString[Ceiling[o/2]]];
    WriteLine[spmx, StringJoin[{pitch[{}, pL[[o, 1]], 3], " ", 
       pitch[pL[[o, 1 ;; 1]], pL[[o, 2]], 1], " ",
       pitch[pL[[o, 1 ;; 2]], pL[[o, 3]], 1], " ",
       pitch[pL[[o, 1 ;; 3]], pL[[o, 4]], 1], " ",
       pitch[pL[[o, 1 ;; 4]], pL[[o, 5]], 1], " r2 /"}]
     ];
    WriteLine[spmx, StringJoin[{pitch[{}, pR[[o, 1]], 3], " ", 
       pitch[pR[[o, 1 ;; 1]], pR[[o, 2]], 1], " ",
       pitch[pR[[o, 1 ;; 2]], pR[[o, 3]], 1], " ",
       pitch[pR[[o, 1 ;; 3]], pR[[o, 4]], 1], " ",
       pitch[pR[[o, 1 ;; 4]], pR[[o, 5]], 1], " r2 /"}]
     ]
    ];
   Close[spmx];
   (* write the footer *)
   spmx = OpenAppend[fNpmx];
   WriteLine[spmx, "%------------------------%"];
   WriteLine[spmx, "%"];
   WriteLine[spmx, "%  end of " <> FileNameTake[fNpmx]];
   WriteLine[spmx, "%"];
   WriteLine[spmx, "%------------------------%"];
   Close[spmx];
   (* call musixtex, if RunProcess works again *)
   (* show the pdf, if RunProcess works again *)
   Print[FileByteCount[fNpmx], " bytes written to \"", fNpmx, "\""]
   ] /; (sym == "d" || sym == "gs") && 1 <= step <= 7 && 
   1 <= rep <= 12 && Length[notes] == 5 && Length[Sort[notes]] == 5 &&
    VectorQ[notes, IntegerQ] && Sort[fLeft] == Range[5] && 
   Sort[fRight] == Range[5]

call this like

pianoLesson["d", {1, 10, 3, 5, 9}, 1, 12, {1, 2, 5, 3, 4 }, {1, 5, 2, 3, 4}]
Exercise 17 appears in "N:\Udo\Abt_N\..\Abt_M\finger_17.pmx
1866 bytes written to "N:\Udo\Abt_N\..\Abt_M\finger_17.pmx"

it writes input to the PMX preprocessor to MusiXTeX. So next one calls MusiXTeX

N:\Udo\Abt_M>musixtex finger_17.pmx
This is musixtex.lua version 0.15.
 This is PMX, Version 2.7  , 3 Apr 13
 Opening finger_17.pmx

 Starting first PMX pass
<snip>
<C:/Program Files (x86)/MiKTeX 2.9/fonts/type1/public/amsfonts/cm/cmr10.pfb>
<C:/Program Files (x86)/MiKTeX 2.9/fonts/type1/public/musixtex-fonts/musixspx.pfb>
[1]
finger_17.pdf generated by ps2pdf.

N:\Udo\Abt_M>

and looks into the PDF sheet:

enter image description here

keep in mind, that the well-temperated keyboard has no cruel dissonances, but only a too hard attack.

POSTED BY: Udo Krause
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract