lilypond-user
[Top][All Lists]
Advanced

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

Re: ! Please answer interesting functionality question for PhD Diss


From: Thomas Morley
Subject: Re: ! Please answer interesting functionality question for PhD Diss
Date: Sun, 25 Oct 2020 11:40:25 +0100

Hi Jean,

Am Sa., 24. Okt. 2020 um 11:55 Uhr schrieb Jean Abou Samra <jean@abou-samra.fr>:

> The problem so far is that I didn't find a proper way to set the chord 
> configuration at a given musical moment (note heads placed at the left or at 
> the right of the stem). For now I've used an extra-offset, which leads to 
> inconsistent spacing. There is \override Stem.note-collision-threshold = 50, 
> but that doesn't let you achieve the fourth chord before the end, where the 
> upper note is on the left and the lower note is on the right, since the usual 
> placement is the other way around.

Stem.note-collision-threshold gives you some possibilities, but to
freely position note-heads at a Stem, one needs to tackle
Stem.positioning-done.

#(define (distribute-note-heads-around-stem note-head-shifts)
  (lambda (grob)
  "Takes the note-heads from a stem-grob and applies offsets in X-direction
taken from @var{note-head-shifts}."
    (let* ((nhds-array (ly:grob-object grob 'note-heads))
           (nhds-list
             (if (ly:grob-array? nhds-array)
                 (ly:grob-array->list nhds-array)
                 '()))
           (sorted-nhds
             (sort
               nhds-list
               (lambda (p1 p2)
                 (ly:pitch<?
                   (ly:prob-property (ly:grob-property p1 'cause) 'pitch)
                   (ly:prob-property (ly:grob-property p2 'cause) 'pitch)))))
           (stem-starting-nhd?
             (lambda (nhd)
               (if (positive? (ly:grob-property grob 'direction))
                   (equal? nhd (car sorted-nhds))
                   (equal? nhd (last sorted-nhds))))))

      ;; Move note-heads in X-direction, looking at 'note-head-shifts'
      ;; If a stem starts at a moved note-head, adjust this note-head's
      ;; 'stem-attachment
      (for-each
        (lambda (nhd nhd-shift)
          (if (and (stem-starting-nhd? nhd) (not (zero? nhd-shift)))
              (let ((default-stem-attach
                      (ly:note-head::calc-stem-attachment grob)))
                (ly:grob-set-property! nhd 'stem-attachment
                  (cons (car default-stem-attach)
                        (- (cdr default-stem-attach))))))
          (ly:grob-translate-axis! nhd
            (* nhd-shift
               (-
                  (interval-length (ly:grob-extent nhd nhd X))
                  (interval-length (ly:grob-extent grob grob X))))
          X))
        nhds-list
        note-head-shifts)
      #t)))

distributeNoteHeads =
#(define-music-function (nhd-shifts)(number-list?)
"Returns an override to distribute note-heads around a stem, according to
@var{nhd-shifts}."
  (if (not (every ly:dir? nhd-shifts))
      (let ((signs (map (@@ (lily) sign) nhd-shifts)))
        (ly:warning
          "Only directions like -1, 0, 1 are accepted, transforming ~a to ~a."
          nhd-shifts
          signs)
        ;; sign should really be public
        (set! nhd-shifts (map (@@ (lily) sign) nhd-shifts))))
  #{
    \override Stem.positioning-done =
      #(distribute-note-heads-around-stem nhd-shifts)
  #})

{
  %% Test the warning
  \once \distributeNoteHeads #'(1.1 0)
  < ees' gis' >

  \voiceTwo
  \once \distributeNoteHeads #'(0 -1)
  < e' g' >
}

> Code attached, with an output that resembles the image you (Michael) sent 
> earlier. Note that you need a development version of LilyPond 
> (lilypond.org/development). Naturally, this is only a start since at this 
> point more details are needed about the specification of what you want to 
> achieve. Nevertheless, I wanted to share this code to avoid duplication of 
> effort in case someone else were willing to take over this topic.

To your comment:
% Not defined?
#(define pi (acos -1))

It's defined in lily-library,scm as
(define-public PI (* 4 (atan 1)))

Cheers,
  Harm



reply via email to

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