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 } >>