[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