lilypond-user
[Top][All Lists]
Advanced

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

Chromatic clashes


From: Lukas-Fabian Moser
Subject: Chromatic clashes
Date: Fri, 16 Apr 2021 23:13:02 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.7.1

Folks,

while the following musical constellation is ugly in the first place, I think we can agree that LilyPond's rendering is less than ideal:

\version "2.22.0"

{ <c' cis'> 4 }

yielding

If we force an accidental to c, we get something that might have a slightly higher probability of being interpreted as intended:

\version "2.22.0"

{ <c'! cis'> 4 }

My questions are:

(1) Do you folks agree that the default behaviour qualifies as a bug?
(2) Is there an easy way to force LilyPond to add the additional natural sign automatically?

(Of course I know that in manually entered scores, one would simply add one ! and be done with it; but that is more difficult in my context, where I'm working with algorithmically generated chords.)

For what it's worth, I think I found a not-quite-easy way for (2), which I'm happy to share of course (see below), but I am doubtful that this is the most elegant solution...

Lukas


\version "2.22.0"

#(define (mark-duplicates els)
   ; given a list of elements, produces a same-length list of
   ; booleans indicating, for each element of the given list;
   ; if it has a twin in the list.
   ; e.g. input '(1  2  3  4  1  5  6  3)
   ;     output '(#t #f #t #f #t #f #f #t)
   (if (pair? els)
       (let* ((head (car els))
              (tail (cdr els))
              (tail-duplicates (mark-duplicates tail))
              (twin-in-tail (list-index (lambda (n) (eq? n head)) tail)))
         (if twin-in-tail
             (begin
              (list-set! tail-duplicates twin-in-tail #t)
              (cons #t tail-duplicates))
             (cons #f tail-duplicates)))
       '()))

chromatic_clash_engraver =
#(let ((note-events '()))
   (make-engraver
    (listeners
     ((note-event engraver event)
      (set! note-events (cons event note-events))))
    ((process-music translator)
     (let* ((pitches (map (lambda (ev) (ly:event-property ev 'pitch))
                          note-events))
            (pitch-steps (map ly:pitch-steps pitches))
            (clashes (mark-duplicates pitch-steps)))
       (for-each (lambda (ev clash?)
                   (if clash? (ly:event-set-property! ev 'force-accidental #t)))
                 note-events clashes))
     (set! note-events '()))))

\layout {
  \context {
    \Staff
    \consists \chromatic_clash_engraver
  }
}

{ <c' cis'> }



reply via email to

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