2017-09-30 11:46 GMT+02:00 Thomas Morley <[email protected]>:
> Hi all,
>
> consider the code below
>
> \score {
>   \relative c' {
>     <c e g b>4\glissando
>     <d' fis g bes>\glissando
>     <c, e g ais>
>   }
>   %% for better viewing:
>   \layout {
>     ragged-right = ##f
>     \override Glissando.color = #red
>     \override Glissando.thickness = 2.5
>   }
> }
>
> I want to create an override which should end all glissandi (starting
> at the NoteHeads of a certain NoteColumn) at the same X-coordinate
> left from all target-NoteHeads.
>
> I tried:
>
> #(define same-gliss-end
>   (lambda (grob)
>     (let* ((vertical-axis-group-elts
>              (ly:grob-object (ly:grob-parent grob Y) 'elements))
>            (all-gliss
>              (if (ly:grob-array? vertical-axis-group-elts)
>                  (filter
>                    (lambda (elt)
>                      (grob::has-interface elt 'glissando-interface))
>                    (ly:grob-array->list vertical-axis-group-elts))
>                  '()))
>            (gliss-X
>              (map
>                (lambda (gliss)
>                  (assoc-get 'X (ly:line-spanner::calc-right-bound-info 
> gliss)))
>                all-gliss))
>            (min-x (apply min gliss-X)))
>
>         (ly:grob-set-nested-property! grob '(right-bound-info X) min-x))))
>
> tst = \override Glissando.after-line-breaking = #same-gliss-end
>
> \score {
>   \relative c' {
>       \tst
>     <c e g b>4\glissando
>     <d' fis g bes>\glissando
>     <c, e g ais>
>   }
>   %% for better viewing:
>   \layout {
>     ragged-right = ##f
>     \override Glissando.color = #red
>     \override Glissando.thickness = 2.5
>   }
> }
>
> Which indeed does the job for the first group of glissandi.
> But all other vanish, because I take the glissandi from
> VertivalAxisGroup. Meaning the last call of the override points
> _every_ glissando to the same X-value, which is the minimum-X of _all_
> glissandi of the current system.
>
> Do I overlook something simple?
> If not, how to do it different?
>
> Any hint appreciated!
>
>
> Thanks,
>   Harm

Eventually I've found a method to limit the affected glissandi to
those of the same NoteColumn.
Though, do we really have no direct method to get all glissandi from
every note of an event-chord? As far as I understand 'glissando-index
and glissandoMap are of no help with this.

Anyway, here what I did:

\version "2.19.65"

#(define same-gliss-start-end
  ;; All glissandi between chords should start at the same X-coordinate, same
  ;; for glissando-endings.
  (lambda (grob)
    (let* ((left-bound (ly:spanner-bound grob LEFT))
           (parent-nc (ly:grob-parent left-bound X))
           (vertical-axis-group-elts
             (ly:grob-object (ly:grob-parent grob Y) 'elements))
           ;; Filter VerticalAxisGroup-elements for Glissandi, restricted to
           ;; those starting at the NoteHeads from same NoteColumn.
           ;; Return their 'X-value for start/end
           (relevant-gliss-Xs
             (if (ly:grob-array? vertical-axis-group-elts)
                 (filter-map
                   (lambda (elt)
                     (and
                       (grob::has-interface elt 'glissando-interface)
                       (equal?
                         (ly:grob-parent (ly:spanner-bound elt LEFT) X)
                         parent-nc)
                       (cons
                         (assoc-get 'X
                                    (ly:grob-property elt 'left-bound-info))
                         (assoc-get 'X
                                    (ly:grob-property elt 'right-bound-info)))))
                   (ly:grob-array->list vertical-axis-group-elts))
                 '()))
           ;; Get the most left 'X for the final 'X-value of the end.
           ;; Get the most right 'X for the final 'X-value of the start.
           ;; Override left/right-bound-info with those values.
           (min-x-right (apply min (map cdr relevant-gliss-Xs)))
           (max-x-left (apply max (map car relevant-gliss-Xs))))
      (ly:grob-set-nested-property! grob '(left-bound-info X) max-x-left)
      (ly:grob-set-nested-property! grob '(right-bound-info X) min-x-right))))

\score {
  \relative c' {
      \override Glissando.after-line-breaking = #same-gliss-start-end
    <c e g b>1\glissando
    <d' fis g bes>\glissando
    \break
    %% \grace is used only to show behaviour of broken glissandi
    \grace s16
    <c, e g ais>1
  }
  %% for better viewing:
  \layout {
    ragged-right = ##f
    \override Glissando.color = #red
    \override Glissando.thickness = 2.5
    \override Glissando.breakable = ##t
    %% further customizing possible with tweaks/overrides like:
    %\override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods
    %\override Glissando.minimum-length = 8
    \override Glissando.bound-details.left.padding = #1
    %\override Glissando.bound-details.right.padding = #3
  }
}

@David N
Attached you'll find the full coded feature. I.e. a method to indicate
equal notes in the same chord-voice of a chord-progression.
It's meant for educational purpose.
Maybe a usefull addition to your partwriter, although I didn't test
whether both codings are compatible.

Cheers,
  Harm

Attachment: glissando-indicates-equals-01.pdf
Description: Adobe PDF document

\version "2.19.65"

#(define equal-pitches-gliss
  ;; Only print a Glissando, if left and right bounding notes are the same.
  (lambda (grob)
    (let* ((orig (ly:grob-original grob))
           (siblings (if (ly:grob? orig)
                         (ly:spanner-broken-into orig)
                         '()))
           ;; Get left/right bounds
           ;; For broken glissandi take first/last of siblings into account, to
           ;; get the relevant note-events.
           (left-bound 
             (ly:spanner-bound 
               (if (pair? siblings) (car siblings) grob)
               LEFT))
           (right-bound 
             (ly:spanner-bound 
               (if (pair? siblings) (last siblings) grob)
               RIGHT))
           (left-cause (ly:grob-property left-bound 'cause))
           (right-cause (ly:grob-property right-bound 'cause))
           (bound-pitch=? 
             (and 
               (ly:prob? left-cause)
               (ly:prob? right-cause)
               (equal? 
                 (ly:prob-property left-cause 'pitch)
                 (ly:prob-property right-cause 'pitch)))))
      ;; The glissandi should be bounded by note-events, if not print a warning
      ;; to terminal, but no stencil.
      (ly:grob-set-property! grob 'stencil
        (cond (bound-pitch=? (ly:line-spanner::print grob))
              ((not (and (ly:prob? left-cause) (ly:prob? right-cause)))
               (begin
                 (ly:warning 
                   "No bounding note-events found, no stencil printed")
                 #f))
              (else #f))))))
            
#(define same-gliss-start-end
  ;; All glissandi between chords should start at the same X-coordinate, same
  ;; for glissando-endings.
  (lambda (grob)
    (let* ((left-bound (ly:spanner-bound grob LEFT))
           (parent-nc (ly:grob-parent left-bound X))
           (vertical-axis-group-elts
             (ly:grob-object (ly:grob-parent grob Y) 'elements))
           ;; Filter VerticalAxisGroup-elements for Glissandi, restricted to
           ;; those starting at the NoteHeads from same NoteColumn.
           ;; Return their 'X-value for start/end
           (relevant-gliss-Xs
             (if (ly:grob-array? vertical-axis-group-elts)
                 (filter-map
                   (lambda (elt)
                     (and 
                       (grob::has-interface elt 'glissando-interface)
                       (equal? 
                         (ly:grob-parent (ly:spanner-bound elt LEFT) X)
                         parent-nc)
                       (cons
                         (assoc-get 'X 
                                    (ly:grob-property elt 'left-bound-info))
                         (assoc-get 'X 
                                    (ly:grob-property elt 'right-bound-info)))))
                   (ly:grob-array->list vertical-axis-group-elts))
                 '()))
           ;; Get the most left 'X for the final 'X-value of the end.
           ;; Get the most right 'X for the final 'X-value of the start.
           ;; Override left/right-bound-info with those values.
           (min-x-right (apply min (map cdr relevant-gliss-Xs)))
           (max-x-left (apply max (map car relevant-gliss-Xs))))
      (ly:grob-set-nested-property! grob '(left-bound-info X) max-x-left)
      (ly:grob-set-nested-property! grob '(right-bound-info X) min-x-right))))

%% 'parser'/'location' are present to make it compile with 2.18.2
addGliss =
#(define-music-function (parser location mus)(ly:music?)
"Adds @code{\\glissando} to every found event-chord, unless already present. 
But not to the last event-chord."
  (let* ((evt-chrds (extract-typed-music mus 'event-chord)))
    (if (pair? evt-chrds)
        (for-each
          (lambda (m)
            (let* ((elts (ly:music-property m 'elements))
                   (glissando-present?
                     (any
                       (lambda (elt) (music-is-of-type? elt 'glissando-event))
                       elts)))
              (if (not glissando-present?)
                  (ly:music-set-property! m 'articulations
                    (cons (make-music 'GlissandoEvent)
                          (ly:music-property m 'articulations))))))
          (drop-right evt-chrds 1)))
    mus))
 
    
\score {
  \addGliss
  { 
    \override Glissando.after-line-breaking =
      #(lambda (grob)
         (same-gliss-start-end grob)
         (equal-pitches-gliss grob))
  
    \clef bass
    <c e g b>1
    <d f g bes>
    <c e g b!>
    <d f g bes>2. 
    <cis e fis bes!>4-\tweak bound-details.right.padding #0.5 \glissando
    \break
    <c ees g bes>2. <c ees! f a>4
    <c d f a>2. <des ees ges bes>4
    <d e g b>2. <cis e g a>4
    %% equal notes present, but different voicing, i.e. no glissando-line
    <>^"See comments in code"
    <c d f a>2 <d f g b>
    \bar "||"
    %% trigger printed glissando with changed input order.
    <c d f a>2 <b d f g>
  }
  \layout {
    \override Glissando.color = #red
    \override Glissando.thickness = 2.5
    \override Glissando.breakable = ##t
    %% further customizing possible with tweaks/overrides like:
    \override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods
    \override Glissando.minimum-length = 8
    \override Glissando.bound-details.left.padding = #1
    \override Glissando.bound-details.right.padding = #3
  }
}
_______________________________________________
lilypond-user mailing list
[email protected]
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to