lilypond-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Bass clarinet fingering chart


From: Carl D. Sorensen
Subject: Re: Bass clarinet fingering chart
Date: Tue, 7 Jul 2009 17:55:45 -0600

Mike, great work!

I have some comments below


On 7/7/09 2:46 PM, "Mike Solomon" <address@hidden> wrote:

> Hey lilypond-users,
>     Before I put this on the LSR, please play around with this.
> Specifically, please
> 
> 1) Make it less sprawling.
Decrease your tab settings.  Follow the indentation suggestions given in the
Contributors' Guide, section 7.2

<http://lilypond.org/doc/v2.12/Documentation/devel/contrib-guide/Programming
-without-compiling#Programming-without-compiling>

They'll help you make it less sprawling.


> 2) Find anything that's broken (the below examples work).
> 3) Change layout to better-suit your wind-playing needs.
> 4) Make any and all layout or coding suggestions.
> 
> THANK YOU!!!
> ~Mike

General comment -- LilyPond coding style is to not use variable names like
fsize.  What is f?  font-size would be better.  Similarly, what is val?
> 
> \version "2.13.0"
> 
> #(define (make-number-bcl layout props fsize stretch offset val)
>     (ly:stencil-translate
>         (ly:text-interface::interpret-markup layout props
> (make-general-align-markup X RIGHT (make-general-align-markup Y DOWN (
> markup #:abs-fontsize fsize val)))) (cons (* -0.5 stretch ) (* offset
> stretch) )
>     )
> )

inl, outmk?  bcl, as well

Oh, I finally see.  inl is input-list, outmk is output-markup

> #(define (make-named-bcl inl outmk biglist)
>     (if (eqv? 0 (length inl))
>         outmk
>         (begin
>             (set! outmk (append outmk (if (list-ref inl 0) (list-ref biglist
> 0) (list (markup #:null)))       ))
>             (make-named-bcl (cdr inl) outmk (cdr biglist))
>            
>         )
>     )
> )
> 
> #(define-markup-command (multiphonic layout props inl) (list?)

multiphonic doesn't make much sense to me.  bassClarinetDiagram?

>     (let*
>         (        ;radius of the circles
>             (radius (list-ref inl 0))
>             ;font size, grows and shrinks with radius
>             (fsize (* radius 12))
>             ;degree of stretch of the holes as a function of radius size.
> Make 0.0 to 0.5 for good results.
>             (spread (list-ref inl 1))
>             (stretch (+ (* 2 radius) (* spread radius)) )
>             ;more or less the approximation from the bible
>             (PI 3.14159265)
No need to make PI this many digits; 4 decimal places is sufficient.

>             ;list of left keys
>             (lbiglist
left-key-list instead of lbiglist (then the comment isn't needed, the code
is self-documenting).
>                 (list
>                     (list (markup #:abs-fontsize fsize "B"))
>                     (list (markup #:abs-fontsize fsize "F")
                            (markup #:abs-fontsize fsize #:raise 1
#:fontsize -2 #:sharp))

Note that I stacked the two arguments to the (list ) procedure to deal
better with line breaking.

>                     (list (markup #:abs-fontsize fsize "E"))
>                     (list (markup #:abs-fontsize fsize "E") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:flat))
>                     (list (markup #:abs-fontsize fsize "G") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:sharp))
>                     (list (markup #:abs-fontsize fsize "F"))
>                 )
>             )
>             ;list of right keys
>             (rbiglist
>                 (list
>                     (list (markup #:abs-fontsize fsize "A"))
>                     (list (markup #:abs-fontsize fsize "G") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:sharp))
>                     (list (markup #:abs-fontsize fsize "E") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:flat))
>                     (list (markup #:abs-fontsize fsize "C") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:sharp))
>                     (list (markup #:abs-fontsize fsize "F"))
>                     (list (markup #:abs-fontsize fsize "E"))
>                     (list (markup #:abs-fontsize fsize "F") (markup
> #:abs-fontsize fsize #:raise 1 #:fontsize -2 #:sharp))
>                 )
>             )
>             ;bools for the fill/non-fill holes
>             (h0 (list-ref inl 2)) (h1 (list-ref inl 3)) (h2 (list-ref inl
> 4)) (h3 (list-ref inl 5)) (h4 (list-ref inl 6)) (h5 (list-ref inl 7)) (h6
> (list-ref inl 8)) (rkey (list-ref inl 9))
I'd put these each on a separate line, rather than dumping them all into one
line.  My rule for (let ) is that every variable definition needs to start
at the exact same column.


>             ;necessary schtuff for the left named keys

Use "stuff", not "schtuff".  Non-native-english speakers may not catch the
meaning, and be unable to find the word in a dictionary.
 
>             (lkeyl (list-ref inl 10)) (lkeymkp (list (markup #:null)))
> (lkeymkp (make-named-bcl lkeyl lkeymkp lbiglist))
>             ;necessary schtuff for the right named keys
>             (rkeyl (list-ref inl 11)) (rkeymkp (list (markup #:null)))
> (rkeymkp (make-named-bcl rkeyl rkeymkp rbiglist))
>             ;values to draw the "R" hole
>             (halfbase (* radius (cos (/ PI 10))) )  (height (* halfbase (/
> (sin (/ (* 4 PI) 10)) (cos (/ (* 4 PI) 10))) ))  (hoffset (* radius (sin (/
> PI 10))) )
>             ;values taking care of numbered key layout
>             (numberkeys (list-ref inl 12)) (nkoffset (- 3.5 (* (- (length
> numberkeys) 1) 0.5)) )
>         )
>         (interpret-markup layout props
>             (markup #:stencil
>                 (ly:stencil-add
>                     ;center holes
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h5) (* 1.0 stretch)
> Y
>                     )
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h4) (* 2.0 stretch)
> Y
>                     )
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h3) (* 3.0 stretch)
> Y
>                     )
>                     (ly:stencil-translate-axis
>                         (ly:make-stencil (list 'draw-line 0.1 (* -1.5
> radius) 0 (* 1.5 radius) 0 ) (cons 0 0 ) (cons 0 0)) (* 3.75 stretch) Y
>                     )
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h2) (* 4.5 stretch)
> Y
>                     )
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h1) (* 5.5 stretch)
> Y
>                     )
>                     (ly:stencil-translate-axis
>                         (make-circle-stencil radius 0.1 h0) (* 6.5 stretch)
> Y
>                     )

Don't match parentheses at indentation levels for Scheme programming.  The
close parenthesis should be at the end of the previous line.

>                     ;left-of-center hole
>                     (if h6
>                         (ly:stencil-translate
>                             (make-circle-stencil radius 0.1 #t) (cons (*
> -1.0 stretch ) (* 6.5 stretch) )
>                         )
>                         empty-stencil
>                     )
>                     ;"R" hole
>                     (if rkey
>                         (ly:stencil-translate
>                             (make-circle-stencil radius 0.1 #t) (cons (*
> -1.0 stretch ) (* 7.5 stretch) )

(* -1.0 stretch)  can be more easily written as (- stretch)

7.5 is some kind of magic number, and shouldn't be included in the code.  If
it can't be a calculation, then it should be defined by name in a (let ) and
the name should be used here.

Or better yet, all of the location information should be put in a list (or
an alist), and you could just call one routine (draw-hole hole-number) to
return a stencil with the proper coordinates for that hole.  If you coupled
that with the idea of a hole-list, rather than a list of booleans (see
below), this could greatly reduce the size of the code.

>                         )
>                         empty-stencil
>                     )
>                     (if rkey
>                         (ly:stencil-translate
>                             (ly:make-stencil `(polygon ',(list halfbase 0.0
> 0.0 height (* -1 halfbase) 0) 0.1 #t) (cons 0 0) (cons 0 0)) (cons (* -1.0
> stretch ) (+ (* 7.5 stretch) hoffset) )

The relevant part can be written more simply like this:

(ly:make-stencil `(polygon (,halfbase 0.0 0.0 ,height ,(# -1 halfbase) 0.1
#t) '(0 . 0) '(0 . 0))

But why do you want the extent of the stencil to be (0 . 0) for both X and
Y?  This will mess up collision resolution things, I think.
                   
>                         )
>                         empty-stencil
>                     )
>                     ;numbered holes.  uggggly....fix me!
>                     (if (> (length numberkeys) 0) (make-number-bcl layout
> props fsize stretch nkoffset (list-ref numberkeys 0)) empty-stencil)
>                     (if (> (length numberkeys) 1) (make-number-bcl layout
> props fsize stretch (+ 1 nkoffset) (list-ref numberkeys 1)) empty-stencil)
>                     (if (> (length numberkeys) 2) (make-number-bcl layout
> props fsize stretch (+ 2 nkoffset) (list-ref numberkeys 2)) empty-stencil)
>                     ;left side named holes
>                     (ly:stencil-translate
>                         (ly:text-interface::interpret-markup layout props
> (make-general-align-markup X RIGHT (make-concat-markup lkeymkp))) (cons (*
> -0.5 stretch ) (* 0.0 stretch) )
>                     )
>                     ;right side named holes
>                     (ly:stencil-translate
>                         (ly:text-interface::interpret-markup layout props
> (make-general-align-markup X LEFT (make-concat-markup rkeymkp))) (cons (*
> 0.5 stretch ) (* 4.0 stretch) )
>                     )
>                 )
>             )
>         )
>     )
> )
> 
> % USEAGE \relative c' { c1^\markup { \multiphonic #(list radius spacing of
> holes hole0 hole1 hole2 hole3 hole4 hole5 hole6 holeR (bottom-o-bcl B F# E
> Eb G# F  ) (middle-o-bcl A G# Eb C# F E F#)
> (left-side-keys-from-top-to-bottom-max-4)  ) }  }

radius and hole-spacing  (use "hole-spacing", not "spacing of holes",
because "spacing of holes" indicates three list elements, not one) probably
need to be arguments if you're going to put this in the LSR.  But if you're
going to add it to LilyPond (which I think you should), these values will be
properties, not arguments.  I'll be happy to help you get this ready to be
added to LilyPond, if you're interested.

I think the interface of having a list of 8 boolean values is awkward.  I'd
recommend that you replace it with a list that indicates which holes should
have the value true.  So instead of '(#f #t #f #t #f #t #f #t), you could
pass the argument '(1 3 5 R).  It would be much easier to type and to
troubleshoot.

For right now, it might be better to have the arguments look like this:

radius hole-spacing ((hole-list) (bottom-o-list) (middle-o-list)
(left-side-list))

This would have three arguments, so it fits in the markup function
capabilities, and the lists for keys and holes are all clustered together
logically.

I believe it would be relatively simple to create a KeyDiagram context based
on the FretBoards context.  And then there could be a predefinedKeyDiagrams
data structure like the predefinedFretBoards structure, and the interface to
the markup generator could be stored in that structure.  Then, key diagrams
could be automatically created from the music.

If you're interested in adding this capability, I'd be happy to help you.
As I said before, I think this is great stuff.

Carl






reply via email to

[Prev in Thread] Current Thread [Next in Thread]