lilypond-user
[Top][All Lists]
Advanced

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

Re: test spanner with controlled gradient / dynamic volume curve indicat


From: Michael Winter
Subject: Re: test spanner with controlled gradient / dynamic volume curve indicated by grey level
Date: Wed, 31 Jan 2018 15:30:07 -0600
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.5.2

ok. I have learned a tremendous amount with your help. I went ahead and hacked away replacing your function with line markups and now it seems to work with line breaks. let me know if you see anything wrong with this.

Best,

Michael

-----------------------



\version "2.18"

\paper { ragged-right = ##f }

\layout {
  \context {
      \Staff
      \override StaffSymbol.line-count = #1
      \remove "Clef_engraver"
      \remove "Time_signature_engraver"
  }
  \context {
      \Voice
      \override Glissando.minimum-length = #0
      %% n.b. line-breaks are TODO
      \override Glissando.breakable = ##t
      \override Glissando.after-line-breaking = ##t
      \override Glissando.bound-details =
        #'((right
             (attach-dir . 0)
             (end-on-accidental . #f)
             (padding . 0.))
           (left
             (attach-dir . 0)
             (padding . 0.)))
    }
}

#(define (make-grey-filled-path-list x-coords color-steps half-thick)
  (if (null? (cdr x-coords))
      (markup )
      (make-combine-markup

       (make-override-markup
               (cons (quote line-cap-style) (quote square))
               (make-with-color-markup
                (x11-color
              (string->symbol (format #f "grey~a" (car color-steps))))
         (make-path-markup half-thick
          (list (list 'moveto (car x-coords) 0)
            (list 'lineto (cadr x-coords) 0)))))

      (make-grey-filled-path-list
        (cdr x-coords)
        (cdr color-steps)
        half-thick
       ))))

#(define my-gliss
  (lambda (grob)
    (if (ly:stencil? (ly:line-spanner::print grob))
        (let* ((stencil (ly:line-spanner::print grob))
               (X-ext (ly:stencil-extent stencil X))
               (left-bound-info (ly:grob-property grob 'left-bound-info))
               (left-Y (assoc-get 'Y left-bound-info))
               (left-X (interval-start X-ext))
               (right-bound-info (ly:grob-property grob 'right-bound-info))
               (right-X (interval-length X-ext))
               (thick (ly:grob-property grob 'thickness 0.5))
               (delta-X (- right-X left-X))
               (steps
                 (assoc-get 'color-steps (ly:grob-property grob 'details) 100))
               (raw-color-steps
                 (iota (abs steps) 0 (round (/ 100 (min 100 (abs steps))))))
               (color-steps
                 (if (negative? steps)
                     (reverse raw-color-steps)
                     raw-color-steps))
               (x-coords (iota (1+ (abs steps)) 0 (/ delta-X (abs steps)))))
          ;; create a flat glissando
          (ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)

          ;; return the stencil of added boxes
          (ly:stencil-translate-axis

           (grob-interpret-markup grob
          (markup
         (make-grey-filled-path-list
          x-coords
          color-steps
          thick)))

            ;; the actual offset is TODO, hardcoded here
            3
            Y))
         #f)))

#(define (add-gliss m)
   (case (ly:music-property m 'name)
     ((NoteEvent)
      (set! (ly:music-property m 'articulations)
            (append
              (ly:music-property m 'articulations)
              (list (make-music 'GlissandoEvent))))
      m)
     (else #f)))

addGliss =
#(define-music-function (parser location music)
  (ly:music?)
  (map-some-music add-gliss music))

%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%

mus =
  {
    \time 2/4
    \addGliss {
      \override Glissando.stencil = #my-gliss
      b'16 b'16 b'8 b'4 \break
      \override Staff.Beam.color = #(x11-color 'grey60)
      b'8 b'16 b'16 ~
    }
    %% n.b. If glissando-skip is #t \addGliss needs to be interrupted
    %% otherwise a programming error occurs
    \once \override NoteColumn.glissando-skip = ##t
    b'16
    \addGliss {
      b'16 b'8
    }
    %% a final target for the last glissando needs to be present, otherwise
    %% lily complains about unterminated glissando
    b'8
  }

\new Score
<<
\new Staff \mus

\new Staff {
  %% negative value reverses colors
  \override Glissando.details.color-steps = -100
  %% thicker
  \override Glissando.thickness = 2
  \mus
}

\new Staff {
  %% less steps, default (and max) is 100
  \override Glissando.details.color-steps = 5
  %% thinner
  \override Glissando.thickness = 0.2
  \mus
}
>>






On 01/31/2018 12:02 PM, Michael Winter wrote:
Another option for the line breading is to give the target final note for a system, hide it (basically the last note in your example). then in the next system. do the same with the starting note on the left side and hide it. Kind of a hack, but could actually look nice because you would see the full extent of the gradient on both the end of one system and the beginning of the next. See below a quick mockup.

I am now curious what you are thinking about the line breaking. Maybe I am out to lunch here and you have a much better idea. I will wait to hear from you before I do any heavy lifting.

Best,

Michael

--------------------------

\version "2.18"

\paper { ragged-right = ##f }

\layout {
  \context {
      \Staff
      \override StaffSymbol.line-count = #1
      \remove "Clef_engraver"
      \remove "Time_signature_engraver"
  }
  \context {
      \Voice
      \override Glissando.minimum-length = #0
      %% n.b. line-breaks are TODO
      \override Glissando.breakable = ##t
      \override Glissando.after-line-breaking = ##t
      \override Glissando.bound-details =
        #'((right
             (attach-dir . 0)
             (end-on-accidental . #f)
             (padding . 0.))
           (left
             (attach-dir . 0)
             (padding . 0.)))
    }
}

#(define (make-grey-filled-box-stencil-list x-coords color-steps half-thick rl)
  (if (null? (cdr x-coords))
      rl
      (make-grey-filled-box-stencil-list
        (cdr x-coords)
        (cdr color-steps)
        half-thick
        (cons
          (stencil-with-color
            (make-filled-box-stencil
              (interval-widen (cons (car x-coords) (cadr x-coords)) 0.1)
              (cons (- half-thick) half-thick))
            (x11-color
              (string->symbol (format #f "grey~a" (car color-steps)))))
          rl))))

#(define my-gliss
  (lambda (grob)
    (if (ly:stencil? (ly:line-spanner::print grob))
        (let* ((stencil (ly:line-spanner::print grob))
               (X-ext (ly:stencil-extent stencil X))
               (left-bound-info (ly:grob-property grob 'left-bound-info))
               (left-Y (assoc-get 'Y left-bound-info))
               (left-X (interval-start X-ext))
               (right-bound-info (ly:grob-property grob 'right-bound-info))
               (right-X (interval-length X-ext))
               (thick (ly:grob-property grob 'thickness 0.5))
               (delta-X (- right-X left-X))
               (steps
                 (assoc-get 'color-steps (ly:grob-property grob 'details) 100))
               (raw-color-steps
                 (iota (abs steps) 0 (round (/ 100 (min 100 (abs steps))))))
               (color-steps
                 (if (negative? steps)
                     (reverse raw-color-steps)
                     raw-color-steps))
               (x-coords (iota (1+ (abs steps)) 0 (/ delta-X (abs steps)))))

          ;; create a flat glissando
          (ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)

          ;; return the stencil of added boxes
          (ly:stencil-translate-axis
            (apply
              ly:stencil-add
              (make-grey-filled-box-stencil-list
                x-coords
                color-steps
                thick
                '()))
            ;; the actual offset is TODO, hardcoded here
            -8
            Y))
         #f)))

#(define (add-gliss m)
   (case (ly:music-property m 'name)
     ((NoteEvent)
      (set! (ly:music-property m 'articulations)
            (append
              (ly:music-property m 'articulations)
              (list (make-music 'GlissandoEvent))))
      m)
     (else #f)))

addGliss =
#(define-music-function (parser location music)
  (ly:music?)
  (map-some-music add-gliss music))

%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%

mus =
  {
    \addGliss {
      \override Glissando.stencil = #my-gliss
      b'16 b'16 b'8 b'4
      \override Staff.Beam.color = #(x11-color 'grey60)
      b'8 b'16 b'16 ~
    }
    %% n.b. If glissando-skip is #t \addGliss needs to be interrupted
    %% otherwise a programming error occurs
    \once \override NoteColumn.glissando-skip = ##t
    b'16
    \addGliss {
      b'16 b'8
    }
    %% a final target for the last glissando needs to be present, otherwise
    %% lily complains about unterminated glissando
    \time 1/8  \stopStaff \hide Stem \hide b'8 \break

    \addGliss {
      \override Glissando.stencil = #my-gliss
      \hide Stem \hide b'8 \startStaff \time 4/4
      b'16 b'16 b'8 b'4
      \override Staff.Beam.color = #(x11-color 'grey60)
      b'8 b'16 b'16 ~
    }
    %% n.b. If glissando-skip is #t \addGliss needs to be interrupted
    %% otherwise a programming error occurs
    \once \override NoteColumn.glissando-skip = ##t
    b'16
    \addGliss {
      b'16 b'8
    }
    %% a final target for the last glissando needs to be present, otherwise
    %% lily complains about unterminated glissando
    \time 1/8  \stopStaff \hide Stem \hide b'8 \break

    \addGliss {
      \override Glissando.stencil = #my-gliss
      \hide Stem \hide b'8 \startStaff \time 4/4
      b'16 b'16 b'8 b'4
      \override Staff.Beam.color = #(x11-color 'grey60)
      b'8 b'16 b'16 ~
    }
    %% n.b. If glissando-skip is #t \addGliss needs to be interrupted
    %% otherwise a programming error occurs
    \once \override NoteColumn.glissando-skip = ##t
    b'16
    \addGliss {
      b'16 b'8
    }
    %% a final target for the last glissando needs to be present, otherwise
    %% lily complains about unterminated glissando
    \time 1/8 \stopStaff \hide Stem \hide b'8 \break
  }

\new Staff \mus






On 01/31/2018 11:37 AM, Michael Winter wrote:
Hmmm... I made the change to use the stencil extent and that seems to be fine. I am not sure what you are saying about the visibility of the final stencil.

As for linebreaking. That is indeed a showstopper at the moment. Is that because you are using filled box stencil? When I was using a path directive with a line, the breaking seemed to work / break fine. I will see if I can make the switch unless you have another idea.

Best,

Michael


On 01/31/2018 03:41 AM, Thomas Morley wrote:
2018-01-31 3:46 GMT+01:00 Michael Winter <address@hidden>:
On first glance. This looks ideal. THANK YOU

I am a bit brain dead at the moment, so will dig in tomorrow and let you
know if I have any further questions / thoughts / ideas.

Glad you like it.
I've found a weakness, though: the stencils overlap. Visible, if you
apply box-stencil to the final stencil.
Probably one should go for stencil-extent to get the extension in
X-axis and not for 'X from left/right-bound-info.
Will have a look in the evening.
Also, linebreaks are not yet working.

Cheers,
   Harm







reply via email to

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