\version "2.14.2" % Thanks to David Nalesnik \pointAndClickOff % #(set-global-staff-size 20) \paper { tagline = ##f indent = 0 } xy = \once\override Stem #'french-beaming = ##t xyOut = #(define-music-function (parser location y-length)(number?) #{ \once \override Stem #'stencil = #(lambda (grob) (ly:grob-set-property! grob 'stem-end-position $y-length) (ly:stem::print grob)) #}) #(define ((grow-beam-var number) grob) (cond ((< (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming))) 2) (ly:beam::print grob)) ((or (= number 0) (and (< number 0) (> (abs number)(1- (ly:grob-array-length (ly:grob-object grob 'stems)))))) (begin (ly:grob-set-property! grob 'grow-direction LEFT) (ly:beam::print grob))) ((>= number (1- (ly:grob-array-length (ly:grob-object grob 'stems)))) (begin (ly:grob-set-property! grob 'grow-direction RIGHT) (ly:beam::print grob))) ((ly:stencil? (ly:beam::print grob)) ;; delete this? (let* ((beam (ly:beam::print grob)) (beam-positions (ly:grob-property grob 'positions)) (beam-slant (cond ((<= (car beam-positions) (cdr beam-positions)) 1) ;;((= (car beam-positions) (cdr beam-positions)) 0) ((> (car beam-positions) (cdr beam-positions)) -1))) (dir (ly:beam::calc-direction grob)) (b-d (ly:output-def-lookup (ly:grob-layout grob) 'blot-diameter)) (beam-extent-X (ly:stencil-extent beam X)) (beam-length-x-orig (interval-length beam-extent-X)) (beam-length-x (- beam-length-x-orig b-d)) (beam-extent-Y (ly:stencil-extent beam Y)) (beam-length-y (interval-length beam-extent-Y)) (orig-beam-thickness (ly:grob-property grob 'beam-thickness)) (beam-count (length (cdr (ly:grob-property (ly:grob-parent grob X) 'beaming)))) (space-between-beams (* 0.46 (ly:grob-property grob 'gap))) (orig-beam-length-at-stem (+ (* beam-count orig-beam-thickness)(* (- beam-count 1) space-between-beams))) (orig-slope (* beam-slant (/ (- beam-length-y orig-beam-length-at-stem) beam-length-x))) (alpha (atan orig-slope)) (beam-thickness (* 0.8 orig-beam-thickness)) (h-max (- (/ orig-beam-length-at-stem (cos alpha)) (* 1.3 beam-thickness))) (number-a (if (integer? (abs number)) (abs number) (inexact->exact (truncate (abs number))))) (number-b (- (abs number) (truncate (abs number)))) (stems (ly:grob-object grob 'stems)) (stem-count (ly:grob-array-length stems)) (refp (ly:grob-system grob)) (first-stem (ly:grob-array-ref stems 0)) (first-stem-dir (ly:grob-property first-stem 'direction)) (last-stem (ly:grob-array-ref stems (- stem-count 1))) (last-stem-dir (ly:grob-property last-stem 'direction)) (target-stem (if (< (abs number-a) stem-count) (ly:grob-array-ref stems number-a) (ly:grob-array-ref stems (- stem-count 1 )))) (next-stem (if (< (+ (abs number-a) 1) stem-count) (ly:grob-array-ref stems (+ number-a 1)) (ly:grob-array-ref stems (- stem-count 1 )))) (first-stem-coord (ly:grob-relative-coordinate first-stem refp X)) (target-stem-coord (ly:grob-relative-coordinate target-stem refp X)) (next-stem-coord (ly:grob-relative-coordinate next-stem refp X)) (first-stem-to-target-stem-length (interval-length (cons first-stem-coord target-stem-coord))) (stem-to-next-stem-length (interval-length (cons target-stem-coord next-stem-coord))) (factor (/ beam-length-x (+ first-stem-to-target-stem-length (* number-b stem-to-next-stem-length)))) (y-sp (lambda (n) (* -1 n dir (+ beam-thickness space-between-beams)))) (y-off (* 1 (/ (- beam-length-y orig-beam-length-at-stem) factor))) ;; markup-a is the longest beam (markup-a (markup #:beam beam-length-x orig-slope beam-thickness)) ;; left piece ;; y-length of left piece (y-L (lambda (n) (if (>= number 0) (- (/ (- beam-length-y orig-beam-length-at-stem) factor) (* dir beam-slant n (/ h-max (- beam-count 1)))) (+ (/ (- beam-length-y orig-beam-length-at-stem) factor) (* dir beam-slant n (+ beam-thickness space-between-beams))) ))) ;; x-length of left piece (x-L (+ first-stem-to-target-stem-length (* number-b stem-to-next-stem-length))) ;; slope of left piece (slope-part-beam-L (lambda (n) (if (>= number 0) (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0))) (/ (y-L n) x-L)) ((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0))) (* -1 (/ (y-L n) x-L)))) (cond ((or (and (> dir 0) (> beam-slant 0))(and (< dir 0) (> beam-slant 0))) (/ (y-L n) x-L)) ((or (and (> dir 0) (< beam-slant 0))(and (< dir 0) (< beam-slant 0))) (* -1 (/ (y-L n) x-L)))) ))) ;; construct left piece (part-beam-L (lambda (n) (markup #:beam x-L (slope-part-beam-L n) beam-thickness))) ;; markup of left piece (markup-L (lambda (n) (markup (part-beam-L n)))) ;; stencil of left piece (beam-part-L (lambda (n) (grob-interpret-markup grob (markup-L n)))) ;; y-extent of left piece (beam-part-L-ext-y (lambda (n) (ly:stencil-extent (beam-part-L n) Y))) ;; length of left piece (length-beam-part-L-y (lambda (n) (interval-length (beam-part-L-ext-y n)))) ;; right piece (y-R (lambda (n) (- (- beam-length-y orig-beam-length-at-stem) (y-L n)))) (x-R (- beam-length-x x-L)) (slope-part-beam-R (lambda (n) (cond ((or (and (> dir 0) (> beam-slant 0)) (and (< dir 0) (> beam-slant 0))) (/ (y-R n) x-R)) ((or (and (> dir 0) (< beam-slant 0)) (and (< dir 0) (< beam-slant 0))) (* -1 (/ (y-R n) x-R)))))) (part-beam-R (lambda (n) (markup #:beam (- beam-length-x x-L) (slope-part-beam-R n) beam-thickness))) (markup-R (lambda (n) (markup (part-beam-R n)))) ;; parts of feathered beams (beam-pieces (map (lambda (n) (ly:stencil-combine-at-edge (ly:stencil-translate-axis (ly:stencil-translate-axis (grob-interpret-markup grob (markup-L n)) -0.025 X) (if (>= number 0) 0 (y-sp n)) Y) X RIGHT (ly:stencil-translate-axis (grob-interpret-markup grob (markup-R n)) (if (>= number 0) (cond ((and (> dir 0)(> beam-slant 0)) (if (and (>= (slope-part-beam-L n) 0)(>= (slope-part-beam-R n) 0)) (- (length-beam-part-L-y n) beam-thickness) (* -1 (- (length-beam-part-L-y n) beam-thickness)))) ((and (> dir 0)(< beam-slant 0)) (* -1 (- (length-beam-part-L-y n) beam-thickness))) ((and (< dir 0)(> beam-slant 0)) (- (length-beam-part-L-y n) beam-thickness)) ((and (< dir 0)(< beam-slant 0)) (if (and (<= (slope-part-beam-L n) 0)(<= (slope-part-beam-R n) 0)) (* -1 (- (length-beam-part-L-y n) beam-thickness)) (- (length-beam-part-L-y n) beam-thickness))) ) (cond ((or (and (> dir 0)(> beam-slant 0))(and (< dir 0)(> beam-slant 0))) y-off) ((or (and (> dir 0)(< beam-slant 0))(and (< dir 0)(< beam-slant 0))) (* -1 y-off)) ) ) Y) 0)) (cdr (iota beam-count)))) ) ;; end of defs in let* (define (helper beam-pieces) (ly:stencil-add (car beam-pieces) (if (null? (cdr beam-pieces)) (car beam-pieces) (helper (cdr beam-pieces))))) (ly:stencil-translate-axis (ly:stencil-add ;; first (long beam) (ly:stencil-translate-axis (grob-interpret-markup grob markup-a) -0.025 X) ;; other beams (helper beam-pieces)) (car beam-positions) ;;beam-thickness Y) ) ;; end of let* ) ) ) #(define (moment=? a b) (not (or (ly:moment? a b) (not (or (ly:moment= turnaround-orig 0)) turnaround-orig (inexact->exact (floor (abs turnaround-orig))))) (elements (ly:music-property argument 'elements)) (dif (- (length elements) turnaround)) (lth (cond ((>= dif 0) dif) (else (length elements)))) (peak-multiplier (reduce (lambda (mom prev) (ly:moment-mul mom prev)) multiplier (make-list turnaround factor))) (end-multiplier (reduce (lambda (mom prev) (ly:moment-mul mom prev)) peak-multiplier (append (list peak-multiplier) (make-list lth ;;(- (length elements) turnaround) (ly:moment-div (ly:make-moment 1 1) factor))))) (comparison (if (< (ly:moment-main-numerator factor) (ly:moment-main-denominator factor)) (lambda (a b) (ly:moment? a b))))) (music-map (lambda (mus) (if (and (eq? (ly:music-property mus 'name) 'EventChord) (< 0 (ly:moment-main-denominator (ly:music-length mus)))) (begin ;;(display multiplier) (newline) ; shows pattern of modification (ly:music-compress mus multiplier) (if (comparison peak-multiplier multiplier) (set! multiplier (ly:moment-mul factor multiplier)) (begin (set! multiplier (ly:moment-div multiplier factor)) (set! peak-multiplier end-multiplier))))) mus) argument) (ly:music-compress argument (ly:moment-div orig-duration (ly:music-length argument))) argument)) %} %{ %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% revised %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% #(define (construct-moment-list len seed factor turnaround) (let* ((whole (ly:make-moment 1 1)) (multiplier whole) (reciprocal (ly:moment-div whole factor)) (turnaround (if (and (integer? turnaround) (>= turnaround 0)) turnaround (inexact->exact (floor (abs turnaround))))) (turnaround (if (> turnaround len) len turnaround)) (moment-list '())) (let loop ((x 0)) (if (= x turnaround) (set! factor reciprocal)) (set! moment-list (append moment-list (cons (ly:moment-mul seed multiplier) '()))) (set! multiplier (ly:moment-mul multiplier factor)) (if (= x (1- len)) moment-list (loop (1+ x)))))) featherDurationsTest= #(define-music-function (parser location factor turnaround argument) (ly:moment? number? ly:music?) (let* ((orig-duration (ly:music-length argument)) (whole (ly:make-moment 1 1)) (elements (ly:music-property argument 'elements)) (moment-series (construct-moment-list (length elements) whole factor turnaround))) (music-map (lambda (mus) (if (and (eq? (ly:music-property mus 'name) 'EventChord) (< 0 (ly:moment-main-denominator (ly:music-length mus)))) (begin (ly:music-compress mus (car moment-series)) (set! moment-series (cdr moment-series)))) mus) argument) (ly:music-compress argument (ly:moment-div orig-duration (ly:music-length argument))) argument)) %} %--------------------- Test ---------------------------------------------------- \relative c' { %\once \override Beam #'stencil = #(grow-beam-var -4) % \once\override Beam #'quantized-positions = #(stem-change 20 -4) c32[ d e f g a b c] s128 \once \override Beam #'stencil = #(grow-beam-var 4) c,32[ d e f g a b c] s128 } %%{ \markup \column { \bold \fill-line { "EXAMPLES" } \vspace #2 } \markup \bold "negative argument" \relative c' { \mark\markup { \with-color #red "A" } \once \override Beam #'stencil = #(grow-beam-var -4) c32[ d e f g a b c] s128 \mark\markup { \with-color #red "B" } \once \override Beam #'stencil = #(grow-beam-var -5) c,32[ d e f g a b c] \mark\markup { \with-color #red "C" } \once \override Beam #'stencil = #(grow-beam-var -3.5) a1024[ g f e d c b a] \mark\markup { \with-color #red "D" } \once \override Beam #'stencil = #(grow-beam-var -2.5) a''''32[ a, a, a, a, a,] \bar "" \break \mark\markup { \with-color #red "E" } \once \override Beam #'stencil = #(grow-beam-var -5) c''32 [d' e, f g a b, c d'' e f g, a b c d ] \mark\markup { \with-color #red "F" } \once \override Beam #'stencil = #(grow-beam-var -5) c,,32 [d e f g a b c d e f g a b c d ] \bar ""\break \mark\markup { \with-color #red "G" } \once \override Beam #'stencil = #(grow-beam-var -5) c32 [b a g f e d c b a g f e d c b ] \mark\markup { \with-color #red "H" } \once\override Beam #'stencil = #(grow-beam-var -5) c,32 [c' c' c,, c d e f g c e b' c' ] \bar ""\break \mark\markup { \with-color #red "J" } \once \override Beam #'stencil = #(grow-beam-var -5) c,,,32[ e g b d f a c] \mark\markup { \with-color #red "K" } \once\override Beam #'stencil = #(grow-beam-var -2) c,,256[c' c' c' c'] \bar "" \break \mark\markup { \with-color #red "L" } \once \override Beam #'positions = #'(0 . 0.1) \once \override Beam #'stencil = #(grow-beam-var 5) f,,,,,32 [ \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xyOut #0 f'''] \once \override Beam #'positions = #'(-1 . 0.5) \once \override Beam #'stencil = #(grow-beam-var -5) \xyOut #0.8 f,,, [\xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xyOut #0.5 f'''] } % --> http://lsr.dsi.unimi.it/LSR/Item?id=508 \new PianoStaff << \new Staff = "RH" { \clef treble \time 3/4 s2 } \new Staff = "LH" { \clef bass \time 3/4 s2 } \context Staff = LH \relative { \mark\markup { \column { \vspace #3 \with-color #red "M" } } \stemDown \once\override Beam #'stencil = #(grow-beam-var -5) \override Beam #'concaveness = #0 c,,32 [ g' \change Staff = RH d' a' e' b' fis' cis'] \once\override Beam #'stencil = #(grow-beam-var -5) cis32 [fis, b, e, a, d, \change Staff = LH g, c, ] } >> one = \relative c' { \once\override Beam #'stencil = #(grow-beam-var -5) c'32 [c c c c c c c c c c c c c c c] c2 } two = \relative c' { \once\override Beam #'stencil = #(grow-beam-var -5) c,16 [c c c c c c c c c c c c c c c] } <<{ \one } \\ {\two }>> \relative c'' { \mark\markup { \column { \vspace #3 \with-color #red "N" } } \override Hairpin #'minimum-length = #5 \override Beam #'stencil = #(grow-beam-var -5) a1*1/8\< s4.\! s8\> s s s8\! a16 [a a a a a a a a a a a a a a a] a32 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a64 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a2 } \pageBreak \relative c' { \mark\markup { \with-color #red "O" } %\once \override Beam #'positions = #'(0.2 . 0.2) \override Beam #'auto-knee-gap = #4 \override Beam #'stencil = #(grow-beam-var -16) c''32 [b a g f g a b c b a g f g a b \xy e,,, c''' b a g a b c d c b a g a b c] \bar "" \break \override Beam #'auto-knee-gap = #4 \override Beam #'stencil = #(grow-beam-var -16) c32 [b a g f g a b c b a g f g a b \xy e,,, c''' b a g a b c d c b a g a b c] } \relative c'' { \mark\markup { \with-color #red "P" } \override Beam #'stencil = #(grow-beam-var -3.5) \featherDurationsTest #(ly:make-moment 4 1) #3.5 {c32[ c c c c c c c] c2.} } \relative c'' { \override Beam #'stencil = #(grow-beam-var -8) \featherDurationsTest #(ly:make-moment 2 1) #8 {a64 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a]} a2| } top = \change Staff = "1" bottom = \change Staff = "2" music = \relative c { \mark\markup { \with-color #red "Q" } \override Beam #'auto-knee-gap = #0 \set tupletSpannerDuration = #(ly:make-moment 1 16) \override TupletNumber #'transparent = ##t \override Beam #'stencil = #(grow-beam-var -1) \once \override Beam #'positions = #'(4.5 . 5) \times 2/3 { \bottom c32[ g' \top eis'] \once \override Beam #'positions = #'(-4.5 . -6) c'[ e, \bottom g,] \top e''[ \bottom \xy c,, \top g''] } \override Beam #'stencil = #(grow-beam-var -2) %\revert Beam #'stencil %\once \override Beam #'positions = #'(3.5 . 5) \once \override Beam #'positions = #'(2 . 4) \times 4/5 { \bottom \xyOut #8.5 c,,64[ \top \xy g'' \xy e' \bottom c,, \top \xyOut #-10 c''] } } \score { \new PianoStaff << \new Staff = "1" { s4 } \new Staff = "2" { \clef bass \music } >> } \relative c'' { \mark\markup { \with-color #red "R" } \featherDurationsTest #(ly:make-moment 2 1) #16 \override Beam #'stencil = #(grow-beam-var -16) {a32 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a]} } \relative c'' { \override Beam #'stencil = #(grow-beam-var -1) c''' [c,, c,,,,] \xyOut #-3 e'''' [\xy f,,,,,, \xyOut #0 g''] } %--------------------- Test 2 -------------------------------------------------- \pageBreak \markup \bold "positive argument" \relative c' { \mark\markup { \with-color #red "A" } \once \override Beam #'stencil = #(grow-beam-var 0) c512[ d e f g a b c] s128 \mark\markup { \with-color #red "B" } \once \override Beam #'stencil = #(grow-beam-var 5) c,32[ d e f g a b c] \mark\markup { \with-color #red "C" } \once \override Beam #'stencil = #(grow-beam-var 3.5) a64[ g f e d c b a] \mark\markup { \with-color #red "D" } \once\override Beam #'stencil = #(grow-beam-var 5) c,32 [c c c c c c c c c c c c c c c ] \bar "" \break \mark\markup { \with-color #red "E" } \once \override Beam #'stencil = #(grow-beam-var 5) c''32 [d' e, f g a b, c d'' e f g, a b c d ] \mark\markup { \with-color #red "F" } \once \override Beam #'stencil = #(grow-beam-var 5) c,,32 [d e f g a b c d e f g a b c d ] \bar ""\break \mark\markup { \with-color #red "G" } \once \override Beam #'stencil = #(grow-beam-var 5) c32 [b a g f e d c b a g f e d c b ] \mark\markup { \with-color #red "H" } \once\override Beam #'stencil = #(grow-beam-var 5) c,32 [c' c' c,, c d e f g c e b' c' ] \bar ""\break \mark\markup { \with-color #red "J" } \once \override Beam #'stencil = #(grow-beam-var 5) c,,,32[ e g b d f a c] \mark\markup { \with-color #red "K" } \once\override Beam #'stencil = #(grow-beam-var 4) c,,256[c' c' c' c'] \bar "" \break \mark\markup { \with-color #red "L" } \once \override Beam #'positions = #'(0 . 0) \once \override Beam #'stencil = #(grow-beam-var -5) \xyOut #3 f,,,,,32 [ \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xyOut #0 f'''] \override Beam #'auto-knee-gap = #6 \once \override Beam #'stencil = #(grow-beam-var 5) f,, [f'' f,, f'' f,, f'' f,, f''] } % --> http://lsr.dsi.unimi.it/LSR/Item?id=508 \new PianoStaff << \new Staff = "RH" { \clef treble \time 3/4 s2 } \new Staff = "LH" { \clef bass \time 3/4 s2 } \context Staff = LH \relative { \mark\markup { \column { \vspace #3 \with-color #red "M" } } \stemDown \once\override Beam #'stencil = #(grow-beam-var 5) \override Beam #'concaveness = #0 c,,32 [ g' \change Staff = RH d' a' e' b' fis' cis'] \once\override Beam #'stencil = #(grow-beam-var 5) cis32 [fis, b, e, a, d, \change Staff = LH g, c, ] } >> one = \relative c' { \once\override Beam #'stencil = #(grow-beam-var 5) c'32 [c c c c c c c c c c c c c c c] c2 } two = \relative c' { \once\override Beam #'stencil = #(grow-beam-var 5) c,16 [c c c c c c c c c c c c c c c] } <<{ \one } \\ {\two }>> \relative c'' { \mark\markup { \column { \vspace #3 \with-color #red "N" } } \override Hairpin #'minimum-length = #5 \override Beam #'stencil = #(grow-beam-var 5) a1*1/8\< s4.\! s8\> s s s8\! a16 [a a a a a a a a a a a a a a a] a32 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a64 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a] a2 } \pageBreak \relative c' { \mark\markup { \with-color #red "O" } \once \override Beam #'positions = #'(-0.8 . -0.8) \override Beam #'auto-knee-gap = #4 \override Beam #'stencil = #(grow-beam-var -16) c''32 [b a g f g a b c b a g f g a b \xy e,,, c''' b a g a b c d c b a g a b c] \bar "" \break \override Beam #'auto-knee-gap = #4 \once \override Beam #'positions = #'(-0.8 . -0.8) \override Beam #'stencil = #(grow-beam-var 16) c32 [b a g f g a b c b a g f g a b e,,, c''' b a g a b c d c b a g a b c] } \relative c'' { \mark\markup { \with-color #red "P" } \override Beam #'stencil = #(grow-beam-var 3.5) \featherDurationsTest #(ly:make-moment 1 4) #3.5 {c32[ c c c c c c c] c2.} } \relative c'' { \override Beam #'stencil = #(grow-beam-var 8) \featherDurationsTest #(ly:make-moment 1 2) #8 {a64 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a]} a2| } \relative c { \mark\markup { \with-color #red "Q" } \once \override Beam #'positions = #'(0 . 0) \once \override Beam #'stencil = #(grow-beam-var -5) \xyOut #3.5 f32 [ \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xy f''' f,,, \xyOut #0 f'''] } top = \change Staff = "1" bottom = \change Staff = "2" music = \relative c { \mark\markup { \with-color #red "R" } \override Beam #'auto-knee-gap = #0 \set tupletSpannerDuration = #(ly:make-moment 1 16) \override TupletNumber #'transparent = ##t \override Beam #'stencil = #(grow-beam-var -1) \once \override Beam #'positions = #'(4.5 . 5) \times 2/3 { \bottom c32[ g' \top \xyOut #-11.5 eis'] \once \override Beam #'positions = #'(-4.5 . -6) c'[ e, \bottom \xyOut #9 g,] \top e''[ \bottom \xy c,, \top g''] } \override Beam #'stencil = #(grow-beam-var 2) %\once \override Beam #'positions = #'(3.5 . 5) \once \override Beam #'positions = #'(4 . 4) \times 4/5 { \bottom c,,64[ \top \xy g'' \xy e' \bottom c,, \top \xyOut #-10 c''] } } \score { \new PianoStaff << \new Staff = "1" { s4 } \new Staff = "2" { \clef bass \music } >> } \relative c'' { \mark\markup { \with-color #red "S" } \once \override Beam #'stencil = #(grow-beam-var -16) \featherDurationsTest #(ly:make-moment 2 1) #16 {a32 [a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a a]} } %}