----- Original Message ----- From: "Thomas Morley" <[email protected]>
To: "David Kastrup" <[email protected]>
Cc: "lilypond-user" <[email protected]>
Sent: Saturday, October 12, 2013 2:29 PM
Subject: Re: Piano/Xylophone key diagrams


2013/10/12 David Kastrup <[email protected]>:
"Phil Holmes" <[email protected]> writes:

At college, one of my ensembles is a mixed-music group performing
modern music.  I normally get away with singing or "playing" a
triangle and bits of other untuned percussion.  Imagine my surprised
when I was given a xylophone piece to play.  Fortunately, it's only
one note at a time, and most of them are the same note, repeated for
four bars, so I generally have the time to work out where the next key
is when I'm playing the current one.  However, I thought it might be
interesting and vaguely useful to have some piano key diagrams which
show which key is to be played, rather like the fingering diagrams.
The attached image illustrates the kind of thing: playing D#.

I know I could use box, rounded-box or filled-box, or moveto/lineto
commands to draw the boxes, so I clearly could create the diagrams
individually for each note.  However, I thought it would be better to
create a function to do this.  I'd presume the location of each box
would be in some sort of array/list, and that the function would use
the 'pitch of the note to determine which to fill.  However, I've read
our documentation on scheme and am stuck on how to start, either
creating the array/list and iterating over it to draw boxes, or
grabbing the pitch value of a note.

Could anyone start me off on this and help when I get stuck again?

Starting off would be on
<URL:http://code.google.com/p/lilypond/issues/detail?id=3563#c4>.  Check
its output.  This is basically what you need, except that you need to
replace the C-Griff function which uses filled and non-filled circles in
a three-row arrangement with a more tedious rectangular arrangement.

The c-griff function here only does the formatting and would need to be
completely replaced.  In contrast, the stuff in define-scheme-function
could be kept unchanged.

Or maybe
http://lsr.dsi.unimi.it/LSR/Item?id=791
might give some inspiration.

Cheers,
 Harm

Thanks to David and Harm for their suggestions. For now I've gone with adapting what Harm suggested - I've tidied the code a little and added a scaling parameter that varies the width of the keys and the size of the dot. Example output is attached, together with the file used to create this.

--
Phil Holmes

<<attachment: Keys_new.png>>

#(define KEY-POS-LIST '(       
   (c    .    1) (cis  .  1.5) (des . 1.5) (d    .    2) (dis  .  2.5) (ees  .  2.5) (e   .  3) 
   (f    .    4) (fis  .  4.5) (ges . 4.5) (g    .    5) (gis  .  5.5) (aes  .  5.5) (a   .  6) 
   (ais  .  6.5) (bes  .  6.5) (b   .   7)))

#(define (black-key? num )
   (member num '(cis  des  dis  ees  fis  ges  gis  aes  ais  bes)) )

#(define (key-to-pos key ypos scale)
  (let ((keypos (assq key KEY-POS-LIST)))
   (if (not keypos)
    (ly:error (_ "keyboard diagram error - unknown note '~a'") key)
    (cons (* (- (cdr (assq key KEY-POS-LIST)) 0.5) scale) (+ (* (- scale 1) 0.32) ypos)))))

#(define (make-keys l1 width off height scale)
   (if (null? l1) 
       empty-stencil
       (ly:stencil-add 
          (ly:stencil-translate
            (make-line-stencil 0.1 0 0 0 height) 
               (cons (* (- (car l1) 1) scale) off ))
          (make-keys (cdr l1) width off height scale))))

#(define (make-keys-black l1 width off height scale)
   (if (null? l1) 
       empty-stencil
       (ly:stencil-add 
          (ly:stencil-translate
            (ly:round-filled-box `(0 . ,(* width scale)) `(0 . ,height) 0) 
               (cons (* (- (car l1) (/ width 2)) scale )  off))
          (make-keys-black (cdr l1) width off height scale))))

#(define (make-dot key scale)
  (if (black-key? key)
    (ly:stencil-in-color 
      (ly:stencil-translate (make-circle-stencil  (* 0.27 scale) 0 #t) (key-to-pos key 2.5 scale)) 1 1 1)
    (ly:stencil-translate (make-circle-stencil  (* 0.32 scale) 0 #t) (key-to-pos key 0.5 scale)) ))

#(define (make-dot-list l1 scale)
   (if (null? l1) 
       empty-stencil
       (ly:stencil-add 
          (make-dot (car l1) scale)
          (make-dot-list (cdr l1) scale ))))

#(define-markup-command (keys layout props arg1 arg2) (list? number?) 
    (ly:stencil-add
      (make-line-stencil 0.1 0 0 (* 7 arg2) 0)
      (make-line-stencil 0.1 0 6 (* 7 arg2)  6)
      (make-keys       '(1 2 3 4 5 6 7 8) 1    0 6 arg2)
      (make-keys-black '(1 2   4 5 6    ) 0.65 2 4 arg2)
      (make-dot-list arg1 arg2)))

key_scale=2.0

\relative c'' {
  \textLengthOn
  b4^\markup\keys #'(b) #1 r r2 r1
  b4^\markup\keys #'(b) #1.5 r r2 r1
  b4^\markup\keys #'(b) #key_scale r r2 r1
  a4^\markup\keys #'(a) #2.5 r r2 r1
  bes4^\markup\keys #'(bes) #3 r r2
}
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to