Jump to content

Adding line breaks in MIDI Karaoke lyrics without disrupting printed score

From LilyPond wiki
(Redirected from LSR 644)

Lyrics can be added with the \addlyrics command, and they will appear in both the layout and midi. The MIDI Karaoke standard allows for the concept of line breaks, usually introduced with either a slash or a backslash at the beginning of a lyric syllable, but placing either of those characters in the lyrics is both messy in the .ly file and disruptive to the printable version (either character will display in the end result).

The perfect solution is to start the lyric syllable with \n - at least, it seems to work with vanBasco's Karaoke Player for Windows (confirmation with other players requested!) However, this is immensely ugly in the LilyPond source:

\addlyrics {
  "\nDoe," a deer, a fe- male deer,
  "\nRay," a drop of gol- den sun,
  "\nMe," a name I call my- self,
  "\nFar," a long long way to run!
}

It's especially ugly if the first word of the line has more than one syllable (the quote in the middle of the word).

With a bit of Scheming, this can be made far cleaner. The function recursively searches its argument for LyricEvents and replaces any leading exclamation mark with a newline.

\addlyrics {
  \lyr {
    !Doe, a deer, a fe- male deer,
    !Ray, a drop of gol- den sun,
    !Me, a name I call my- self,
    !Far, a long long way to run!
  }
}

\version "2.24.0"

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

% For each lyric element that begins with '!', change it to begin with '\n'.
#(define (bang->slashn lst)
   (cond ((null? lst) 0)
         (else (if (equal? (ly:music-property (car lst) 'name) 'LyricEvent)
                   (let ((txt (ly:music-property (car lst) 'text)))
                     (if (equal? (string-ref txt 0) #\!)
                         ;; Prepend a newline instead of the exclamation
                         ;; mark - works for both MIDI Karaoke and page layout
                         (set! (ly:music-property (car lst) 'text)
                               (string-append
                                "\n"
                                (substring txt 1 (string-length txt)))))))
               (bang->slashn (ly:music-property (car lst) 'elements))
               (bang->slashn (cdr lst)))))
               
% Call the above recursive function
lyr =
#(define-music-function (lyrics) (ly:music?)
   (bang->slashn (ly:music-property lyrics 'elements))
   lyrics)

\new Voice {
  c'4 d' e' c'
  e'4 c' e'
}
\addlyrics {
  \lyr {
    !Doe, a deer, a fe- male deer,
    !Ray, a drop of gol- den sun,
    !Me, a name I call my- self,
    !Far, a long long way to run!
  }
}