lilypond-user
[Top][All Lists]
Advanced

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

Re: Vibrato (wavy lines) notation


From: Jean Abou Samra
Subject: Re: Vibrato (wavy lines) notation
Date: Fri, 14 Jan 2022 21:59:31 +0100
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:91.0) Gecko/20100101 Thunderbird/91.3.1

Le 14/01/2022 à 20:41, Valentin Petzel a écrit :
Hello Richard,

The file you’ve given us has a lot of nonsensical quoting in lines 149-153.


Actually, not completely nonsensical, but legacy. There used to
be one more level of quoting inside stencil expressions until

commit 06ba7f0823a14da773391ccf3c10244a54e812d4
Author: Han-Wen Nienhuys <hanwenn@gmail.com>
Date:   Sun Aug 2 21:47:25 2020 +0200

    Dispatch stencil routines using explicit tables

    scm_eval in GUILE became much more elaborate to deal with byte code
    (2.2) and JIT compilation (3.0). This means that scm_eval has more
    overhead for single shot code:

     * setup temporary storage for bytecode/JIT'd x86 code
     * run up and down the syntax tree applying optimizations
     * other magic that compiler folks do to make things run faster

    The Scheme expressions for stencils aren't generalized code; they are
    just a device-independent description of the output. In particular,
    they have no advanced construct (loops, conditionals, tail calls,
    variable bindings, variable references), also, they are run only
    once. So all the work that scm_eval does to produce faster code is
    just overhead.

    The change makes it explicit that the data is just literal data, and
    does the one thing to specialize it from device-independent to
    device-specific, which is replacing symbols with their definitions
    from output-ps.scm

    Because output expression do not pass through eval anymore, we stop
    quoting symbol and list values.

    Backend implementors should take the following changes into account:

    * placebox is removed. Instead each stencil expression is surrounded
      by settranslation and resettranslation

    * ly:make-paper-outputter takes a single function as argument. The
      function takes the Scheme expression, for example,

         (circle 10 0.1 #t)

      as argument.

    * A paper-outputter no longer is associated with a module. For the SVG
      backend, this is solved by creating some backend-specific
      expressions (set-paper, set-unit-length) which the eval-svg function
      treats specially.

    Markup/stencil implementors should take the following changes into
    account:

    * Stencil expressions are no longer passed through the eval
      function. This means that all inner (quasi)quoting should be
      removed.

    Tested
      lilypond -dbackend=svg input/regression/les-nereides

    Timing

    In verbose mode, the backend output phase will print timing. This
    timing leads to the following data for (MSDM-reduced, 2Ghz CPU):

    Current master
    - Guile 1.8: 0.74s
    - Guile 2.2: 4.73s
    - Guile 3.0: 2.49s

    This commit
    - Guile 1.8: 0.80s
    - Guile 2.2: 1.41s
    - Guile 3.0: 1.20s



Basically `(path ...) is already quasi-quoted, so there is no reason to quote
the symbol round (as it is already quoted).


Well, but there was.

`round
=> round

`'round
=> (quote round)

This extra quote was necessary in 2.20.


Also you will get an error for
line 150 where we have

`(,@',(concatenate path-final))

So we first quasi-quote something that is already quasi-quoted, then we create
a list, use an unquote splice operator (,@), which basically evaluates the
expression to a list and then gives the entries of the list instead of the
list (note we are CREATING a list first just to splice something into it –
instead of this we can simply do ,(concatenate path-final)), then we are
quoting the whole thing we just unquoted again to add another unquote, which
does not work as the last quote was not a quasi-quote.

So to get it to work closest to what’s in the file we’d need to do

(,@`,(concatenate path-final))

Or alternatively

,`(,@`,(concatenate path-final))

But much more intelligent would be simply doing this:

,(concatenate path-final)


Yes, in 2.22, and in 2.20 you are right that it
can be simplified, but to ',(concatenate path-final)
with an extra quote at the beginning.

Anyway, here is a largely simplified version of this
snippet:


\version "2.22.1"

#(use-modules (ice-9 match))

#(set-object-property! 'curvature-factor 'backend-type? number?)

vibrato =
#(define-music-function (amplitudes wave-length) (list? number?)
   #{
     \once \override TrillSpanner.normalized-endpoints =
       #ly:spanner::calc-normalized-endpoints
     \once \override TrillSpanner.curvature-factor = 0.35
     \once \override TrillSpanner.stencil =
       #(let* ((n-amplitudes-1 (1- (length amplitudes))))
          (grob-transformer
           'stencil
           (lambda (grob original)
             (if
              (ly:stencil? original)
              (match-let* (((left . right) (ly:grob-property grob 'normalized-endpoints))                             (left-idx (inexact->exact (round (* n-amplitudes-1 left))))                             (right-idx (inexact->exact (round (* n-amplitudes-1 right))))
                            (sublist (match (drop (take amplitudes
                                                   (1+ right-idx))
                                             left-idx)
                                      ((one) (list one one))
                                      (lst lst)))
                            (original-ext (ly:stencil-extent original X))
                            (len (interval-length original-ext))
                            ((start . end) original-ext)
                            (position-increment (/ len (1- (length sublist))))                             (thickness (* (ly:grob-property grob 'thickness 1.0)
(ly:staff-symbol-line-thickness grob)))
                            (factor (ly:grob-property grob 'curvature-factor)))
                (make-path-stencil
                 (append
                  `(moveto ,start 0.0)
                  (let loop ((position start)
                             (tail sublist)
                             (last-exact start)
                             (current-sign 1)
                             (acc '()))
                    (if (>= position end)
                        (reverse! acc)
                        (match-let* ((next-position (+ position wave-length))                                      (intermediate1 (+ position (* wave-length factor)))                                      (intermediate2 (+ position (* wave-length (- 1 factor))))
                                     (from-last (- position last-exact))
                                     ((previous-height next-height . _) tail)                                      (height (* current-sign (interval-index
(cons previous-height next-height)
                                                              (+ -1 (* 2 (/ from-last position-increment))))))                                      (path-component `(curveto ,intermediate1 ,height
,intermediate2 ,height
,next-position 0.0))
                               (new-acc (append-reverse path-component acc)))
                          (if (>= from-last position-increment)
                              (loop next-position
                                    (cdr tail)
                                    (+ last-exact position-increment)
                                    (- current-sign)
                                    new-acc)
                              (loop next-position
                                    tail
                                    last-exact
                                    (- current-sign)
                                    new-acc))))))
                 thickness
                 1
                 1
                 #f))
              '()))))
    #})

{
  \vibrato #'(0.5) #0.5
  c'2\startTrillSpan d' e'\stopTrillSpan
}

{
  \vibrato #'(0.5 2.0) #0.5
  c'2\startTrillSpan d' e'\stopTrillSpan
}

{
  \override TrillSpanner.thickness = 2
  \vibrato #'(0.0 2.0) #3.0
  c'1\startTrillSpan d' \break
  e' e'\stopTrillSpan
}

{
  \override TrillSpanner.bound-details.left.padding = -2
  \vibrato #'(0.5 0.5 8 0.0) #0.8
  c'1\startTrillSpan d' \break
  e' e'\stopTrillSpan
}

{
  \override TrillSpanner.bound-details.left.padding = -2
  \vibrato #'(2.5 3.5 8 0.0) #0.8
  c'1\startTrillSpan d' \break
  e' e'\stopTrillSpan
}


Best regards,
Jean





reply via email to

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