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
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
