[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Slurred staccato in a tremolo
From: |
Thomas Morley |
Subject: |
Re: Slurred staccato in a tremolo |
Date: |
Sun, 8 Mar 2015 22:32:16 +0100 |
2015-03-08 22:12 GMT+01:00 Jacques Menu <address@hidden>:
> Hello Harm,
>
> Couldn’t have even thought of such an expert solution, will all its power...
>
> Congratulations, and thanks!
>
> JM
>
>> Le 8 mars 2015 à 21:46, Thomas Morley <address@hidden> a écrit :
>>
>> 2015-03-08 19:25 GMT+01:00 Klaus Blum <address@hidden>:
>>> Hi Jacques,
>>>
>>> there is already a snippet that might help:
>>> http://lsr.di.unimi.it/LSR/Item?id=772
>>> <http://lsr.di.unimi.it/LSR/Item?id=772>
>>>
>>> Cheers,
>>> Klaus
>>
>> How about the code below.
>> It rewrites and extends said snippet with code from Issue 3088
>>
>>
>>
>> \version "2.19.15"
>>
>> %% https://code.google.com/p/lilypond/issues/detail?id=3088
>>
>>
>> %% FIXME: c&p from stencil.scm -- define-public and remove copy
>> #(define (make-bezier-sandwich-stencil coords thick xext yext)
>> (let* ((command-list `(moveto
>> ,(car (list-ref coords 3))
>> ,(cdr (list-ref coords 3))
>> curveto
>> ,(car (list-ref coords 0))
>> ,(cdr (list-ref coords 0))
>> ,(car (list-ref coords 1))
>> ,(cdr (list-ref coords 1))
>> ,(car (list-ref coords 2))
>> ,(cdr (list-ref coords 2))
>> curveto
>> ,(car (list-ref coords 4))
>> ,(cdr (list-ref coords 4))
>> ,(car (list-ref coords 5))
>> ,(cdr (list-ref coords 5))
>> ,(car (list-ref coords 6))
>> ,(cdr (list-ref coords 6))
>> closepath)))
>> (ly:make-stencil
>> `(path ,thick `(,@' ,command-list) 'round 'round #t)
>> xext
>> yext)))
>>
>> %% FIXME: rewrite generic wrt axes and replace make-parenthesis-stencil
>> #(define (make-bow-stencil width height thickness angularity)
>> "Create a bow stencil.
>> @var{width} is the width of the bow markup.
>> @var{thickness} is the thickness of the bow.
>> @var{height} is the heigth of the bow.
>> The higher the value of number @var{angularity},
>> the more angular the shape of the bow."
>> (let* ((line-width 0.1)
>> (base-x (if (< width 0) (- width) 0))
>> (base-y (if (< height 0) (- height) 0))
>> (x-extent (ordered-cons 0 width))
>> (y-extent (ordered-cons 0 height))
>> (left-x (interval-start x-extent))
>> (right-x (interval-end x-extent))
>> (inner-y 0)
>> (outer-y height)
>> (left-end-point (cons left-x inner-y))
>> (right-end-point (cons right-x inner-y))
>> (outer-control-y (+ inner-y (* 4/3 outer-y)))
>> (inner-control-y (+ outer-control-y
>> (if (< height 0) thickness (- thickness))))
>> ;; keeping angularity allows for refactoring and
>> ;; merging with make-parenthesis-stencil
>> (offset-index (- (* 0.6 angularity) 0.8))
>> (left-control-x (interval-index x-extent offset-index))
>> (right-control-x (interval-index x-extent (- offset-index)))
>> (left-outer-control-point
>> (cons left-control-x outer-control-y))
>> (right-outer-control-point
>> (cons right-control-x outer-control-y))
>> (right-inner-control-point
>> (cons right-control-x inner-control-y))
>> (left-inner-control-point
>> (cons left-control-x inner-control-y)))
>>
>> (make-bezier-sandwich-stencil
>> (list right-inner-control-point
>> left-inner-control-point
>> left-end-point
>> right-end-point
>> left-outer-control-point
>> right-outer-control-point
>> right-end-point
>> left-end-point)
>> line-width
>> x-extent
>> y-extent)))
>>
>> %% FIXME: replace make-parenthesis-stencil by this:
>> #(define (make-parenthesis-stencil height width thick angularity)
>> (ly:stencil-rotate-absolute
>> (make-bow-stencil height width thick angularity)
>> -90 0 0))
>>
>> %% FIXME: c&p from bezier-bow.cc
>> #(define (F0_1 x) (* (/ 2 PI) (atan (* PI x 0.5))))
>> #(define (slur-height w h_inf r_0)
>> (F0_1 (* (/ (* w r_0) h_inf) h_inf)))
>>
>> #(define (make-tie-stencil width thickness direction)
>> (let* ((height-limit 1)
>> (ratio 0.25)
>> (angularity 0.5)
>> (height (slur-height width height-limit ratio))
>>
>> )
>> (make-bow-stencil width (* direction height) thickness angularity)))
>>
>> #(define-markup-command (undertie layout props arg)
>> (markup?)
>> #:category font
>> #:properties ((thickness 1)
>> (offset 2)
>> (direction DOWN)
>> (adjust-length 0)
>> (adjust-x-pos 0))
>> "
>> @cindex undertie-ing text
>>
>> Undertie @var{arg}. Looks at @code{thickness} to determine line
>> thickness, and @code{offset} to determine line y-offset.
>>
>> @lilypond[verbatim,quote]
>> \\markup \\line {
>> \\undertie \"undertied\"
>> \\override #'(offset . 5)
>> \\override #'(thickness . 1)
>> \\undertie \"undertied\"
>> \\override #'(offset . 1)
>> \\override #'(thickness . 5)
>> \\undertie \"undertied\"
>> }
>> @end lilypond"
>> (let* ((line-thickness (ly:output-def-lookup layout 'line-thickness))
>> (thick (* thickness line-thickness))
>> (markup (interpret-markup layout props arg))
>> (x1 (car (ly:stencil-extent markup X)))
>> (x2 (cdr (ly:stencil-extent markup X)))
>> (y2 (cdr (ly:stencil-extent markup Y)))
>> (w (- x2 x1 adjust-length (* 2 line-thickness)))
>> (y (if (positive? direction)
>> (+ line-thickness offset -2 y2)
>> (* line-thickness (- offset))))
>> (tie (ly:stencil-translate
>> (make-tie-stencil w thick direction)
>> (cons (+ line-thickness adjust-x-pos) y))))
>> (ly:stencil-add markup tie)))
>>
>> %% taken from
>> %% http://lsr.di.unimi.it/LSR/Item?id=772
>> %% and rewritten, due to newer syntax possibilities
>> #(define ((multiple-dots dots) grob)
>> (let ((stil (ly:script-interface::print grob)))
>> (let loop ((count (1- dots)) (new-stil stil))
>> (if (> count 0)
>> (loop (1- count)
>> (ly:stencil-combine-at-edge new-stil X RIGHT stil 0.2))
>> (ly:stencil-aligned-to new-stil X CENTER)))))
>>
>> tongue =
>> #(define-event-function (parser location dots) (integer?)
>> "Return a @var{dots} dots, replacing @code{staccato}"
>> #{
>> \tweak #'stencil
>> #(multiple-dots dots)
>> -.
>> #})
>>
>> %% a slurred version
>> slurred-tongue =
>> #(define-event-function (parser location overshoot dots)
>> ((string? "0.3") integer?)
>> "Return a @var{dots} dots, replacing @code{staccato}, a bow will be
>> printed above
>> (or below) those dots.
>> @var{overshoot} determines the horizontal alignment of dots and bow.
>> Needs to be string, otherwise it can't be made optional.
>> "
>> #{
>> \tweak #'stencil
>> #(lambda (grob)
>> (let* ((stil ((multiple-dots dots) grob))
>> (stil-x-length (interval-length (ly:stencil-extent stil X)))
>> (dir (ly:grob-property grob 'direction))
>> (over-shoot (string->number overshoot))
>> )
>> (grob-interpret-markup grob
>> #{
>> \markup
>> \override #`(offset . ,(if (= dir DOWN) 5.2 2.2))
>> \override #`(direction . ,dir)
>> \override #`(adjust-x-pos . ,(+ (- over-shoot)(* -0.5
>> stil-x-length)))
>> \undertie
>> \pad-x #over-shoot
>> \stencil $stil
>> #})))
>> -. %% tweak the staccato
>> #})
>>
>> %%%%%%%%%%%%%%%%%%%
>> %% Example
>> %%%%%%%%%%%%%%%%%%%
>>
>> {
>> \time 3/4
>> \clef "bass"
>> % \voiceOne
>> \repeat tremolo 6 g8\slurred-tongue "0.8" #1 -1
>> \repeat tremolo 6 f8\slurred-tongue #2 \3
>> \repeat tremolo 6 <e g>8\slurred-tongue #3 --
>> \repeat tremolo 6 dis8\slurred-tongue #4 \fermata
>> \repeat tremolo 6 cis8\slurred-tongue #5 -"xy"
>> \repeat tremolo 6 b,8\slurred-tongue #6 _2
>> \repeat tremolo 6 a,8\slurred-tongue #5 _\4
>> \repeat tremolo 6 ges,8\slurred-tongue #4 _\fermata
>> \repeat tremolo 6 fes,8\slurred-tongue #3 _"foo"
>> }
>>
>>
>> HTH,
>> Harm
>>
>> _______________________________________________
>> lilypond-user mailing list
>> address@hidden
>> https://lists.gnu.org/mailman/listinfo/lilypond-user
Glad I could help.
One problem persists, though.
If \voiveXxx is used _and_ other objects like fingerings, TextScript
etc are present, the whole thing is centered above the NoteHead, not
the Stem.
To see the difference, compile:
{
\time 3/4
\clef "bass"
\voiceOne
\repeat tremolo 6 e,8\slurred-tongue #3
\repeat tremolo 6 e,8\slurred-tongue #3 -"foo"
}
Not sure what causes it.
Cheers,
Harm