lilypond-user
[Top][All Lists]
Advanced

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

Re: Help with espressivo adjustments


From: Thomas Morley
Subject: Re: Help with espressivo adjustments
Date: Sat, 13 Apr 2013 02:23:40 +0200

2013/4/12 SoundsFromSound <address@hidden>:
> Thomas:
>
> That works beautifully!
>
> When you get a free moment, could you please break down that code for me
> piece by piece so I can understand how I may be able to edit it in the
> future, if need be (for further adjustments / size changes)?
>
> Thank you again,
>
> Ben

Ok, I'll try, though, please remember I'm not a programmer. My
explanations may be not complete.

I decided to develope the code in step by step manner.
(You'll notice that in the end the code is changed a bit, compared
with my previous post.)

I) PROBLEM
With { f\espressivo } the "espressivo"-sign (i.e. every small hairpin)
should become longer, but not higher.

II) possible SOLUTIONS
a) create a new stencil
b) scale the default-stencil in direction of X-axis

III) THOUGHTS about II)
Solution a) is doable. But will result in a higher coding effort.
Solution b) is cheaper. It's disadvantage is that it will not print
acceptable results in all cases.
(Although you may not know this before you've tried :) )
Result: choose solution b)

IV) CODING
i) If you want to manipulate the default-stencil you have to find/get it.
Looking in the IR
http://lilypond.org/doc/v2.17/Documentation/internals/script
shows:
  stencil (stencil):
      ly:script-interface::print

Let us test if it is correct.
To be sure that I affect the correct grob, I often use colors. There
is a predefined function, which does so:
>From IR
http://lilypond.org/doc/v2.17/Documentation/internals/scheme-functions
  Function: ly:stencil-in-color stc r g b
      Put stc in a different color.

This will result in:

colorDefaultStencil =
\once \override Script #'stencil =
  ;; `lambda´ starts a procedure, it's argument is `grob´
  #(lambda (grob)
     ;; In `let´ local variables are defined.
     (let ((stil (ly:script-interface::print grob)))
     ;; The procedure returns the colored default-stencil:
     (ly:stencil-in-color
       stil
      1 0 0)))

     { \colorDefaultStencil f''\espressivo }

Fine, works.

ii) Wanting to get a scaled stencil, we have to use
  Function: ly:stencil-scale stil x y
      Scale stil using the horizontal and vertical scaling factors x and y.
from the same IR-chapter.

Resulting in:

scaleColorDefaultStencil =
\once \override Script #'stencil =
  #(lambda (grob)
     (let ((stil (ly:script-interface::print grob)))
     (ly:stencil-in-color
       (ly:stencil-scale
         stil
         ;; 1 is the neutrat element with ly:stencil-scale
         ;; i.e. scaling with: 1 1 (for x- and y-axis) returns a not (visible)
         ;; changed stencil.
         2 1)
      1 0 0)))

     { \scaleColorDefaultStencil f''\espressivo }

Well, apart from the color that seems to be the desired output.

iii) Though, there are some problems.

Look at:

     { \scaleColorDefaultStencil <f'' a''>_\espressivo ^\fermata }

a) The fermata is scaled, too.
b) Typing the command before and \espressivo after the note(s) is annoying.

Solution for both: use tweak!

     {
             <f'' a''>
             -\tweak #'stencil
             #(lambda (grob)
                      (let ((stil (ly:script-interface::print grob)))
                      (ly:stencil-in-color
                        (ly:stencil-scale
                          stil
                          2 1)
                       1 0 0)))
             _\espressivo ^\fermata
     }

Does what we want, though, typing this isn't nice.

Ok, let's define a variable and use it with the tweak.

With some copy/paste we get:

#(define longer-script  ;;[1]
  (lambda (grob)
          (let ((stil (ly:script-interface::print grob)))
          (ly:stencil-in-color
            (ly:stencil-scale stil 2 1)
            1 0 0))))

     {
             <f'' a''>
             -\tweak #'stencil #longer-script
             _\espressivo ^\fermata
     }

Works fine, though the scaling values are hard-coded and there might
be the possibility to avoid typing of
   -\tweak #'stencil #longer-script

First, let's introduce some variables in `longer-script´ for scaling
in x- and y-axis:

#(define (longer-script x y)
  (lambda (grob)
          (let ((stil (ly:script-interface::print grob)))
          (ly:stencil-in-color
            (ly:stencil-scale stil x y)
            1 0 0))))

Second, to reduce typing-effort we define an event-function:

scaleScript =
#(define-event-function (parser location x-val y-val)(number? number?)
#{
        \tweak #'stencil #(longer-script x-val y-val)
        \espressivo
#})

{ <f'' a''>_\scaleScript #2 #1 ^\fermata }

Works as expected, fine!

iv) Clean up
- We only want scaling in x-direction: Let's hardcode y-scaling in the
event-function.
- Delete the color.

V) THE FINISHED CODE

\version "2.17.15"

#(define (longer-script x y) ;; [2]
  (lambda (grob)
          (let ((stil (ly:script-interface::print grob)))
          (ly:stencil-scale stil x y))))

longEspressivo =
#(define-event-function (parser location x-val)(number?)
#{
        \tweak #'stencil #(longer-script x-val 1)
        \espressivo
#})

     { f''^\longEspressivo #2 _\fermata }

VI) REMARKS
[1] Coding
    #(define (longer-script x y)
      (lambda (grob)
       ...
or
    #(define ((longer-script x y) grob)
       ...
is nearly the same. It's more a matter of taste.
Sometimes the use of `lambda´ is regarded the more elegant method.

[2] It's possible to affect every grob with this definition, as long
the default-stencil is
`ly:script-interface::print´

In general:
Explaining/commenting is more work than coding itself.
That's the reason why our documentation is sometimes not on the same
level as the functionality of the program. ;)

There might be special, more complex cases, where the code above will not work.
I omitted any comment about these. This would belong to a new thread.

VI) LAST
I didn't explain predefined guile-procedures/macros etc
i.e. "define", "let", "number?"
(or at least not very verbose)
If you're interested to dive in deeper, you may refer to the
guile-manual and/or one of the scheme-tutorials available online.


I hope I forgot nothing important and did not to many typos. ;)



Cheers,
  Harm



reply via email to

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