lilypond-user
[Top][All Lists]
Advanced

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

Re: handbell shake


From: Thomas Morley
Subject: Re: handbell shake
Date: Thu, 31 May 2018 00:40:50 +0200

2018-05-30 0:32 GMT+02:00 Rick Kimpel <address@hidden>:

> 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



reply via email to

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