Hi Eef,
Am 16.09.22 um 13:53 schrieb Eef Weenink:
I write mostly arrangements where I bring a melody voice down to the double
bass (my instrument :-))
Double bass is written an octave higher then sounding, so a lot of times, the
score lookes OK, but in fact there are voice crossings between lefthand of
piano and the double bass (what gives unwanted/unpleasant voice crossings.
To check this, I transpose the double bass voice down an octave and manually
check the boths voices.
Wonder if there is a function in lilypond to do this fastly. Like the coloured
noteheads when checking a voice against the ambitus of an instrument.
This reminds me of a function I wrote last year to automatically
colourise the lowest sounding pitch in a score. (In my case, this was
for harmonic analysis of canons.) See attached.
Maybe this could be used or at least adapted?
Lukas
\version "2.23"
% ==== Bass_highlighter_engraver =====================================
#(set-object-property! 'bass-notehead-callback 'backend-type? procedure?)
#(set-object-property! 'bass-notehead-callback 'backend-doc "Function to be called on grob if it is a bass notehead")
#(define (is-lower-bound? el lst less?)
; returns #t if no element of lst is less? than el.
(if (pair? lst)
(if (less? (car lst) el)
#f
(is-lower-bound? el (cdr lst) less?))
#t))
Bass_highlighter_engraver =
#(lambda (context)
(define (is-over? note moment)
(not (ly:moment<? moment (assq-ref note 'off-time))))
(let ((notes '()))
(make-engraver
(listeners
((note-event engraver event)
(let*
((on-time (ly:context-current-moment context))
(pitch (ly:event-property event 'pitch))
(duration (ly:event-property event 'duration))
(note-length (ly:duration-length duration))
(off-time (ly:moment-add on-time note-length)))
(set! notes (cons `((on-time . ,on-time)
(off-time . ,off-time)
(pitch . ,pitch))
notes)))))
(acknowledgers
((note-head-interface engraver grob source-engraver)
(let* ((event (ly:grob-property grob 'cause))
(pitch (ly:event-property event 'pitch))
(current-pitches
(map (lambda (note) (assq-ref note 'pitch)) notes)))
(if (is-lower-bound? pitch current-pitches ly:pitch<?)
(let
((callback (ly:grob-property grob 'bass-notehead-callback)))
(if (procedure? callback) (callback grob)))))))
((start-translation-timestep translator)
; remove all notes that are over by now
(let* ((now (ly:context-current-moment context)))
(set! notes
(filter (lambda (note) (not (is-over? note now)))
notes)))))))
% =======================================================
\layout {
\context {
\Score
\consists #Bass_highlighter_engraver
\override NoteHead.bass-notehead-callback =
#(lambda (grob) (ly:grob-set-property! grob 'color red))
% interesting alternative:
% #(lambda (grob) (ly:grob-set-property! grob 'duration-log 1))
}
}
% Example:
<<
\new Staff \relative {
c'4 d e f
g a b c
c, d c g
}
\new Staff \relative {
d''4 c b a
g f e d
<c e g> q q q
}
>>