Hi Andrew,

2016-08-02 19:13 GMT+02:00 Thomas Morley <thomasmorle...@gmail.com>:
> 2016-08-02 17:13 GMT+02:00 Andrew Bernard <andrew.bern...@gmail.com>:
>> Hi Harm,
>>
>> Thank you for this. I suppose I was not clear enough, as usual. I
>> explicitly need the beams on the individual note to have a longer
>> beamlet on the top, with the rest being shorter. This is what I am
>> unable to achieve. So it's not the beam break that I can't do, rather,
>> it is the adjustment of the lengths of the beamlets. Can that be done
>> with any lilypond magic?
>>
>> Andrew
>
> Hi Andrew,
>
> next try below ;)
> The comments should explain what's going on, if not shout.
>
> \version "2.19.45"
>
> affectMainBeam =
> #(define-music-function (val-list)(number-pair-list?)
> "
>  We get the 'beam-segments, rebuilding it modified.
>  The 'beam-segments-property is an alist of type:
>     '(((vertical-count . 0) (horizontal 3.865018 . 5.93))
>       ((vertical-count . 1) (horizontal 3.865018 . 5.93)))
>
>     `vertical-count' is the beam-count.
>     `horizontal' is the x-extent relative to 'System!!
>     I.e. the appearance will alter, when spacing changes.
>
>  The values given in @var{val-list} are added to the horizontal extent.
> "
[...]

My previous code aimed at setting the beam-segments directly.
The attached code attempts more to set the gap between beam-segments.

HTH,
  Harm
\version "2.19.45"

#(define (change-beam-segments ls1 ls2)
  (define (helper l1 l2 l3)
  "l1 is supposed to be a list containing number-pairs which are used to change
  the values of the number-list l2, accumulating the result in l3."
    (if (null? l2)
        l3
        (helper (cdr l1) (cdr l2)
          (cons
            (ordered-cons
              ;; get the car of the new beam-segments-extent-pair
              ;;
              ;; If the value of l1 is positive we simply add it to the relevant
              ;; value of l2.
              ;; For the first beam-segment (l3 is empty) we do same. I.e. if 
              ;; the value of l1 is negative the beam will stick out to the left
              ;;
              ;; Otherwise we take the relevant value from l3 building the
              ;; difference with the l1-value. Which will cause inner beam-
              ;; segments to stick out to the left. This will not take any
              ;; affect if the choosen value for the previous beam-segments
              ;; appearance to the right causes a too small gap.
              (if (or (null? l3) (>= (caar l1) 0))
                  (+ (caar l1) (caar l2))
                  (abs 
                    (- (cdar l3) (caar l1)))
                    )
              ;; get the car of the new beam-segments-extent-pair
              ;;
              ;; If the l1-value is positive and we tackle not the last beam-
              ;; segment (i.e. (cdr l2) is not empty) we simply build the
              ;; difference. I.e. the beam-segment will stick out to the right.
              ;; For the last beam-segment we add the relevant values. I.e. the 
              ;; beam-segment will stick out to the right.
              ;; Otherwise we build the difference. This will cause the gap
              ;; between beam-segments move accordingly, iff the used values
              ;; are appropiate.
              (cond ((and (not (null? (cdr l2))) 
                          (positive? (cdar l1)))
                     (- (caadr l2) (cdar l1)))
                    ((null? (cdr l2))
                     (+ (cdar l2) (cdar l1)))
                    (else (- (cdar l2) (cdar l1)))))
            l3))))
   (helper ls1 ls2 '()))
   
%% a little helper to save some typing
setStemBeamCounts =
#(define-music-function (left-right-beam-count)(pair?)
#{
  \set stemLeftBeamCount = $(car left-right-beam-count)
  \set stemRightBeamCount = #(cdr left-right-beam-count)
#})

#(define (beam-segments::change-horizontal-extent vals)
"
 We get the 'beam-segments, rebuilding it modified.
 The 'beam-segments-property is an alist of type:
    '(((vertical-count . 0) (horizontal 3.865018 . 5.93))
      ((vertical-count . 1) (horizontal 3.865018 . 5.93)))

    `vertical-count' is the beam-count.
    `horizontal' is the x-extent relative to 'System!!
    
 The values given in @var{val-list} are applied to the horizontal extent by 
 @code{change-beam-segments}.
 The gap between beam-segments is hereby settable and likely more robust against
 spacing changes.
"
  (lambda (beam)
    (let* (;; get the default beam-segments-list
           (beam-segments (ly:beam::calc-beam-segments beam))
           ;; get the main beam-segments
           (main-beams
             (filter
               (lambda (beam-seg)
                 (zero? (assoc-get 'vertical-count beam-seg)))
               beam-segments))
           ;; get their horizontal extent
           (main-beams-horizontal-ext (map cdadr main-beams))
           ;; create a list with changed values for the horizontal extent
           (equal-gaps
             (change-beam-segments 
               (append vals (circular-list '(0 . 0))) 
               main-beams-horizontal-ext)))
      ;; apply the new calculated values for the horizontal extent to the
      ;; beam-segments.
      ;; This happens destuctively. A problem?
      (for-each
        (lambda (x y) (set-cdr! (cadr x) y))
        main-beams
        equal-gaps)
      ;; return the result 
      beam-segments)))
    
affectMainBeamGap =
#(define-music-function (val-list)(number-pair-list?)
"
 Returns beam-segments with changed horizontal dimension of the main-beam 
 according to the values given by @var{val-list}, which is supposed to be a 
 number-pair-list like: '((-2 . 4) (-2 . 4) (-2 . 2))
 The first value of the first pair will extend the main-beam to the left as does
 the last value of the last pair to the right. Positive value for the first
 negative for the last will have no or unpredictable effect.
 The other values will cause a settable and moveable gap between the 
 main-beam-segments.
 Needs to be applied before the entire Beam starts and relies on settings of
 @code{stemLeftBeamCount} and/or @code{stemRightBeamCount}.
 Limitations:
 No collision-avoidance happens.
 Depending on the values, changed spacing may cause surprises.
 Not tested for kneed beams and Beams over line-break.
"
#{
  \once \override Beam.beam-segments = 
    #(beam-segments::change-horizontal-extent val-list)
#})

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%% EXAMPLE
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

%% In the following example there is _one_ Beam, which has _three_ segments.
%% So the list-argument to `affectMainBeamGap' has three entries.
%% '(0 . 0) is ofcourse the neutral argument
%% If less entries then beam-segments are given sufficient instancies of 
%% '(0 . 0) are added in the function.
%%
%% Not tested for kneed Beams or Beams over line-break.
example = {
  b!32[ 
  \setStemBeamCounts #'(2 . 1)
  a'!16
  \set stemLeftBeamCount = #0
  \times 2/3 { 
    fes'!8 
    \setStemBeamCounts #'(2 . 0)
    f!16 g'!32]~ 
  } 
  g'16
  \bar "|"
  \break
}

music = { 
  \cadenzaOn
  %\textLengthOn
  <>^"Andrew's example"
  \affectMainBeamGap #'((0 . 2) (0 . 0) (-1 . 0))
  \example
  
  <>^"first and last beam-segment changed"
  \affectMainBeamGap #'((-2 . 0) (0 . 0) (0 . 2))
  \example  
  
  <>^"gap between first and second beam-segment"
  \affectMainBeamGap #'((0 . 2) (0 . 0) (0 . 0))
  \example 
  
  <>^"moved gap between first and second beam-segment"
  \affectMainBeamGap #'((0 . 4) (-2 . 0) (0 . 0))
  \example 
  
  <>^"moved gap between first and second beam-segment"
  \affectMainBeamGap #'((0 . 6) (-2 . 0) (0 . 0))
  \example
  
  <>^"bad output"
  \affectMainBeamGap #'((0 . 10) (-2 . 0) (0 . 0))
  \example
}

{ 
  <>_"voiceOne" \voiceOne \music \bar "||" 
  % <>_"voiceTwo" \voiceTwo \music 
}

\paper { ragged-right = ##t indent = 0 }

        
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to