2018-05-30 0:32 GMT+02:00 Rick Kimpel <rick.kim...@outlook.com>: > I am trying to build a library of functions for handbell choir music. The > first thing I attempted was how to show a shake. It sort of looks like a > trill mark, but the squiggly line is at the level of the note being played. > I'm hoping that I can just make a script that does all of this for me, but > the fact that I had to nudge the invisible notehead over by hand has me > worried that this might not be possible. If there's an easier way to do > this, please let me know, especially if it gets rid of all the clash warning > messages. Maybe something like faking the landing note of the gliss? > > > Thanks, > > Rick [...]
Hi Rick, I don't know anything about handbell choir music and which special notation-features may be needed. Are there any images you could link to? >From your coding-attempts, I think you want to mimic the shake with a flat trill-style-glissando. It's not too hard to get this, but glissando needs a target note-head. Meaning a glissando to a rest is impossible (without second voice). Also, suspended NoteHeads in a chord may lead to different start-end points of simultaneous glissandi. All in all it's not far from the problems avantgarde.music using continuation-lines has to face. To circumvent these problems I developed some code for continuation-lines, which I stripped down to better fit your needs (as far as I understood them) It has it's own limitations (see comments), but it may get you started. \version "2.19.81" %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Flat Glissandi %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% %%%% Reads from Glissando.details: %%%% equal-chord-glissando-start-end [defaults to '(#t . #t)] #(define flat-gliss (lambda (grob) (let ((left-Y (assoc-get 'Y (ly:grob-property grob 'left-bound-info)))) ;; create a flat glissando (ly:grob-set-nested-property! grob '(right-bound-info Y) left-Y)))) #(define same-gliss-start-end ;; Looks at details.equal-chord-glissando-start-end whether all glissandi ;; between chords should start at the same X-coordinate, same for ;; glissando-endings ;; 'equal-chord-glissando-start-end?' takes a pair of booleans indicating it. (lambda (grob) (let* ((left-bound (ly:spanner-bound grob LEFT)) (parent-nc (ly:grob-parent left-bound X)) (details (ly:grob-property grob 'details)) (equal-chord-glissando-start-end (assoc-get 'equal-chord-glissando-start-end details '(#t . #t))) (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)) '()))) ;; Depending on `equal-chord-glissando-start-end': ;; Get the most left 'X for the resulting 'X-value of the end. ;; Get the most right 'X for the resulting 'X-value of the start. ;; Override left/right-bound-info with those values. (if (car equal-chord-glissando-start-end) (ly:grob-set-nested-property! grob '(left-bound-info X) (apply max (map car relevant-gliss-Xs)))) (if (cdr equal-chord-glissando-start-end) (ly:grob-set-nested-property! grob '(right-bound-info X) (apply min (map cdr relevant-gliss-Xs))))))) at = #(define-music-function (parser location time event music) (ly:duration? ly:music? ly:music?) "Place @var{event} at a relative duration @var{time} in relation to @var{music}." #{ \context Bottom << { \skip $time <>$event } $music >> #}) %% %% Limitation of `durLine': %% * `mus' can't end exactly before \break %% * not breakable, even if 'breakable is set #t durLine = #(define-music-function (parser location left-right-padding mus) ((pair? '(0.5 . 0)) ly:music?) (let* ((mus-copy (ly:music-deep-copy mus)) (notes (extract-typed-music mus-copy 'note-event)) (mus-to-insert (cond ((music-is-of-type? mus-copy 'event-chord) (make-event-chord (map (lambda (n) (ly:music-set-property! n 'articulations '()) n) notes))) ((music-is-of-type? mus-copy 'note-event) (ly:music-set-property! mus-copy 'articulations '()) mus-copy) (else mus-copy))) (dur (ly:music-property (last notes) 'duration #f))) (if (ly:duration? dur) #{ \at $dur \grace { \once \omit ParenthesesItem \once \omit AccidentalCautionary \override NoteHead.stencil = #point-stencil \override NoteHead.no-ledgers = ##t \override Accidental.stencil = ##f \override Flag.stencil = ##f \override Dots.stencil = ##f \override Stem.stencil = ##f $mus-to-insert \revert NoteHead.stencil \revert NoteHead.no-ledgers \revert Accidental.stencil \revert Flag.stencil \revert Dots.stencil \revert Stem.stencil } { \once \override Score.GraceSpacing.spacing-increment = 0 \once \override Glissando.bound-details.left.padding = #(car left-right-padding) \once \override Glissando.bound-details.right.padding = #(cdr left-right-padding) \once \override Glissando.after-line-breaking = #(lambda (grob) (begin (same-gliss-start-end grob) ;; The following is needed if 'to-barline is set #t ;; TODO why?? (flat-gliss grob))) <>\glissando $(ly:music-deep-copy mus) } #} (ly:music-deep-copy mus)))) \layout { \context { \Voice %% needed to get 'minimum-length work \override Glissando.springs-and-rods = #ly:spanner::set-spacing-rods } } { \durLine <c' d'>4*11 r4 <>^"\\durLine #'(1 . 4)" \durLine #'(1 . 4) <c' d'>4*11 r4 \once \override Glissando.details.equal-chord-glissando-start-end = #'(#f . #t) \durLine #'(1 . 4) <c' d'>4*11 r4 } \new Staff = "topBells" { << \new Voice = "descant" \relative c''' { \voiceOne %\override Glissando.minimum-length = 10 \override Glissando.style = #'trill \durLine g4. f8 e2 r4 <g g,> \once \override Glissando.to-barline = ##t \durLine <c c,>2 g8 c, a' c, } \new Voice = "melody" \relative c'' { \voiceTwo <d d,>4 <d d,> c2 r4. d,8 e4 r e f } >> } HTH, Harm _______________________________________________ lilypond-user mailing list lilypond-user@gnu.org https://lists.gnu.org/mailman/listinfo/lilypond-user