Jump to content

Ghost voice

From LilyPond wiki

This function transforms a simple voice (pitches and durations) into a “ghost voice” consisting of spacers and durations only (e.g. c2 d e ==> s2 s s). This is very useful for writing simultaneous voice parts where one contains pitches, another dynamics, a third fingering instructions ... This can easily be used to print a score with or without fingerings or other attributes! The ghost music can be written to the log with \displayLilyMusic \ghostMusic followed by the music to be transformed.

\version "2.24.0"

%% http://lsr.di.unimi.it/LSR/Item?id=507

%% LSR This snippet was contributed by Gilles Thibault, on an idea by Eluze.
%% updated by Gilles Thibault on Feb. 2014

#(define (MM->Script-text evt)
(if (eq? 'MultiMeasureTextEvent (ly:music-property evt 'name))
  (let ((res (make-music 'TextScriptEvent)))
    ;; (display (ly:music-mutable-properties evt)) ; if you are curious ...
    (for-each (lambda(props)
                 (ly:music-set-property! res (car props) (cdr props)))
               (ly:music-mutable-properties evt))
    res)
  evt))

ghostMusic = #(define-music-function (music) (ly:music? )
(map-some-music 
 (lambda(x)
   (let ((dur (ly:music-property x 'duration #f)))
      (and (or dur (eq? 'EventChord (ly:music-property x 'name)))
           (let ((skip (make-music 'SkipEvent 'duration
                          (or dur (make-duration-of-length (ly:music-length x)))))
                 (artis (let ((elts (ly:music-property x 'elements #f)))
                          (if elts (filter (lambda(y)   ;; EventChord
                                             (not (eq? 'NoteEvent (ly:music-property y 'name))))
                                           elts)
                                   (map MM->Script-text (ly:music-property x 'articulations '()))))))
             (ly:music-set-property! skip 'articulations artis)
             skip))))
  music))

notes = { a2-"hello" b4 r-"1"  R1^"2" b2 a-"bye" <c e g c' e' g'>1-"oho ;-)" }
 
\ghostMusic \notes