Using the LilyPond typesetting program
to publish the sonatas of Domenico Scarlatti


This is useful only for historical purposes now, as LilyPond has evolved considerably since I used it.

The sonatas of Domenico Scarlatti pose unique technical problems to a typesetter. The music is dense - many notes, close together. The original is written as if it were polyphonic, even though it mostly isn't. It ranges over the keyboard to such an extent that Scarlatti abandoned the clef-based notation of his time, and wrote parts that wander all over a pair of staves with fixed clefs. He had the fastest fingers in Europe - 1/32th notes filling a bar are routine occurrences, as are double trills and trills on the middle notes of chords. Finally, he used his hands interchangeably, anywhere on the keyboard, and intertwined, to an extent unequalled by any composer before or since.

LilyPond grew up with these rather remarkable requirements in mind (and others), and my Scarlatti edition grew up along with it. So, this note reflects an Odyssey with the LilyPond typesetting program from 1.1.13, and is an application note for it as I used it for the final sonatas (1.2.16).

The LilyPond language provides for a set of nested containers, called contexts. The Score is a piece of music. It contains a paper block and staff groups - I use PianoStaff. Each staff group contains Staffs - single lines of music. Each Staff contains Voices - sets of notes that are stemmed together. Finally, a Voice contains Threads - notes using the same head. That is:

 Score<
   PianoStaff<
     Staff<
       Voice<
         Thread<
           notes
   > > > >
   paper<
 > >

Each typesetting element must be used in its proper context. The ones I use are:

LilyPond sends its output through the TeX system, where a few more layout parameters may be set. The spacing between staff groups, interscoreline, defaults to 16 pt - I prefer 8. The paper height is also set in TeX, by the geometry command; I use
letterpaper,dvips,left=11mm,width=188mm,top=-6mm,height=278mm,includemp=false
which, together with the LilyPond linewidth 188 mm, permits printing on all laser printers of which I am aware using either letter or A4 paper.

These, plus the spacing parameters mentioned above, are the only means Lily currently has of adjusting the physical length of a score so that it fits neatly on a page. It has to be done manually.

Of course, what would a note like this be without WIBNI's (Wouldn't It Be Nice If...) ?

Some day ...

Procedure

Scarlatti is mass production - 555 sonatas, 2000+ pages. The procedure I use is designed for that:

  1. With a sequencer program (Cubase Compact on Win3.1)
    1. play the score on a MIDI keyboard (in time with a MIDI metronome)
    2. quantize note starts and lengths (to take out my sloppy finger work) with the Cubase editor,
    3. move notes that shouldn't be stemmed together into separate channels, which become separate LilyPond voices,
    4. output a MIDI file;
  2. convert the MIDI file with midi2ly (-b is necessary except for the simplest duple-meter pieces) in Linux;
  3. merge the midi2ly output into a template, thread by thread, with a text editor (I use WordPerfect in NT);
  4. reformat with a BASIC program (lilyconv, in NT) to remove duration repeats, especially \times{}, so that each measure takes one line, convert common compound durations (such as a4~a16) to tied notes, and convert the appropriate number of sharps to flats. (Scarlatti doesn't use keys in the modern sense - this conversion is best selected manually.)
  5. create a TeX envelope file;
  6. reformat with a BASIC program (lilycln) to sequence voice and thread names, put the voice name in the measure number lines output by midi2ly, and indent each thread according to its position within its voice, so I know where I am when I do detailed editing.
  7. process to Postscript with LilyPond (in Linux);
  8. view the result (with Ghostscript in NT);
  9. correct errors, note collisions, stem directions etc. with a text editor in one half of the screen and the Ghostscript view in the other;
  10. repeat 6-9 until I think it's OK, then print (Ghostscript)
  11. play it, then (usually) return for re-edit
  12. zip and post (Cupertino in NT).

All that rebooting does sound rather messy, doesn't it?! It was. But, you see, I do a lot of heavy work in NT, where I can get reliable programs that handle things like 50 MB 24-bit colour photos, 20,000 point GIS maps, CD burning, typesetting and laser printing 100-page books, WYSIWYG word processing, HPGL, HTML, scientific graphing, fast programming of one-off research tasks, sound font creation... and do it all to modern interoperability standards. (I talk to the world, and there aren't many Unix systems out there.) Central to it all is WordPerfect, which gives me an editor with 256 hotkeys, and as many custom GUI's as I need, set up so that everything I need to do is under my fingers in a consistent way. That consistency just doesn't come using a different editor for each task, and few things are more important for speed and accuracy of computer use.

VM Ware was one option to avoid the rebooting, but the truth is I was getting tired of fighting Linux and having to beg for help from gurus every time I wanted to get something done. And so, I switched to the Windows version of Lily. It works - I recommend it.

John Sankey
other notes on computing

Appendix

Here are some of the templates and programs I use. I hope you get a useful idea or two from them for your own work. To convert them for use with Linux, prefix each line with "ugh"   :-)
%template for midi2ly
%K.ly LilyPond 1.2.16
\include "jdsprop.ly";
\score {
\context PianoStaff \notes<
\context Staff=up<
\keysignature;
\time 4/4;
\clef treble;
\autochange Staff
\context Voice = va < \zs
\su
\context Thread=ta { \n
% first block from mi2mu
}>
\autochange Staff
\context Voice = vb < \zs
\sd
\context Thread=tb { \n
% second block from mi2mu
}>
\autochange Staff
\context Voice = vc < \zs
\sd
\context Thread=tc { \n
% third block from mi2mu (if present)
}>
\autochange Staff
\context Voice = vd < \zs
\sd
\context Thread=td { \n
% fourth block from mi2mu (if present)
}>
>
\context Staff=down<
\clef bass;
\keysignature;

>>
\paper{\include "jdspaper.ly";
\translator{\VoiceContext beamAutoBegin=0;}
}}

%jdsprop.ly
rh={\property Thread.noteHeadStyle=""}
lh={\property Thread.noteHeadStyle="diamond"}
n={\property Thread.fontSize="0"}
sm={\property Thread.fontSize="-1"}
su={\property Voice.verticalDirection="1"}
sd={\property Voice.verticalDirection="-1"}
zs={\property Voice.forceHorizontalShift="0.0"}
ls={\property Voice.forceHorizontalShift="-0.6"}
sls={\property Voice.forceHorizontalShift="-0.22"}
rs={\property Voice.forceHorizontalShift="0.6"}
srs={\property Voice.forceHorizontalShift="0.22"}

%jdspaper.ly
0=\font "feta19"
-1=\font "feta16"
arithmetic_multiplier=7.\pt;
indent=0.;
linewidth=188.\mm;
forced_stem_shorten0=0.;
forced_stem_shorten1=0.;
forced_stem_shorten2=0.;
forced_stem_shorten3=0.;
\translator{\PianoStaffContext
  maxVerticalAlign=42.\pt;
  minVerticalAlign=42.\pt;
  \consists Bar_number_engraver;}
\translator{\StaffContext
  timeSignatureStyle="C";}
%The following applies the Voice properties here to all files while
% allowing sonata-specific autobeam additions to be made in each file
VoiceContext=\translator{\VoiceContext
  noStemExtend=1;
  textEmptyDimension=1;
  tupletVisibility=0;};
\translator{\VoiceContext}
\translator{\ThreadContext
  \consists Font_size_engraver;}

10 REM LILYCONV: clean up LilyPond midi2ly output
20 REM It's easy to make a file that blows this! but real mi2mu files
30 REM just need to be converted to ASCII with WordPerfect
40  INPUT "K";K$
50  INPUT "# flats to use";X%
60  OPEN "K"+K$+".mly" FOR INPUT AS 1
70  OPEN "K"+K$+".ly" FOR OUTPUT AS 2
80  REM line input loop
90  IF EOF(1)<>0 THEN 1180
100  LINE INPUT#1,L$
110  REM ***** remove leading tabs & useless spaces *****
120  IF LEN(L$)=0 THEN 80  :REM null line
130  IF ASC(L$)=9 THEN L$=MID$(L$,2): GOTO 110
140  IF ASC(L$)=32 THEN L$=MID$(L$,2): GOTO 110
150  I%=LEN(L$) :REM trailing space
160  IF MID$(L$,I%)=" " THEN L$=MID$(L$,1,I%-1): GOTO 150
170  I%=INSTR(1,L$,"  ")  :REM multiple space
180  IF I%>0 THEN L$=MID$(L$,1,I%)+MID$(L$,I%+2): GOTO 170
190  REM ***** that's all to do for comment lines *****
200  IF MID$(L$,1)="%" THEN 1150
210   REM ***** change sharps to flats *****
220   IF X%<=0 THEN 370   :REM sharp key - nothing to do
230    I%=INSTR(1,L$,"ais")
240    IF I%>0 THEN L$=MID$(L$,1,I%-1)+"bes"+MID$(L$,I%+3): GOTO 230
250    IF X%=1 THEN 370
260    I%=INSTR(1,L$,"dis")
270    IF I%>0 THEN L$=MID$(L$,1,I%-1)+"ees"+MID$(L$,I%+3): GOTO 260
280    IF X%=2 THEN 370
290    I%=INSTR(1,L$,"gis")
300    IF I%>0 THEN L$=MID$(L$,1,I%-1)+"aes"+MID$(L$,I%+3): GOTO 290
310    IF X%=3 THEN 370
320    I%=INSTR(1,L$,"cis")
330    IF I%>0 THEN L$=MID$(L$,1,I%-1)+"des"+MID$(L$,I%+3): GOTO 320
340    IF X%=4 THEN 370
350    I%=INSTR(1,L$,"fis")
360    IF I%>0 THEN L$=MID$(L$,1,I%-1)+"ges"+MID$(L$,I%+3): GOTO 350
370   REM ***** translate regular \skip commands to s *****
380   I%=INSTR(1,L$,"\skip ")
390   IF I%=0 THEN 480          :REM no command left
400    FOR J%=I%+6 TO LEN(L$)   :REM get \skip argument
410     C%=ASC(MID$(L$,J%,1))
420     IF C%=59 THEN 460       :REM ; end of argument
430      IF C%=46 THEN 450      :REM . OK part of argument
440       IF C%<48 OR C%>57 THEN 480 :REM non-numeric - irregular
450    NEXT J%: GOTO 480        :REM (shouldn't get here)
460   L$=MID$(L$,1,I%-1)+"s"+MID$(L$,I%+6,J%-I%-6)+MID$(L$,J%+1)
470   GOTO 370                  :REM continue translating
480   REM ***** translate some \times commands *****
485   REM (this section really does deserve an ugh!)
490   I%=INSTR(1,L$,"\times 5/8 { ")
500   IF I%=0 THEN 660          :REM none of these left
510    J%=INSTR(I%,L$,"1 }")
520    IF J%=0 THEN 560
530    N$=MID$(L$,I%+13,J%-I%-13)
540    L$=MID$(L$,1,I%-1)+N$+"4.~"+N$+"4"+MID$(L$,J%+3)
550    GOTO 490                  :REM continue translating
560    J%=INSTR(I%,L$,"2 }")
570    IF J%=0 THEN 610
580    N$=MID$(L$,I%+13,J%-I%-13)
590    L$=MID$(L$,1,I%-1)+N$+"4~"+N$+"16"+MID$(L$,J%+3)
600    GOTO 490                  :REM continue translating
610    J%=INSTR(I%,L$,"4 }")
620    IF J%=0 THEN 660
630    N$=MID$(L$,I%+13,J%-I%-13)
640    L$=MID$(L$,1,I%-1)+N$+"8~"+N$+"32"+MID$(L$,J%+3)
650    GOTO 490                  :REM continue translating
660   I%=INSTR(1,L$,"\times 7/8 { ")
670   IF I%=0 THEN 770 
680    J%=INSTR(I%,L$,"1 }")
690    IF J%=0 THEN 720
700    N$=MID$(L$,I%+13,J%-I%-13)
710    L$=MID$(L$,1,I%-1)+N$+"2.~"+N$+"8"+MID$(L$,J%+3)
720    J%=INSTR(I%,L$,"2 }")
730    IF J%=0 THEN 770
740    N$=MID$(L$,I%+13,J%-I%-13)
750    L$=MID$(L$,1,I%-1)+N$+"4.~"+N$+"16"+MID$(L$,J%+3)
760    GOTO 660
770   I%=INSTR(1,L$,"\times 10/7 { ")
780   IF I%=0 THEN 840          :REM none of these left
790    J%=INSTR(I%,L$,"4.. }")
800    IF J%=0 THEN 840
810    N$=MID$(L$,I%+14,J%-I%-14)
820    L$=MID$(L$,1,I%-1)+N$+"2~"+N$+"8"+MID$(L$,J%+5)
830    GOTO 770                  :REM continue translating
840   I%=INSTR(1,L$,"\times 12/7 { ")
850   IF I%=0 THEN 900 
860    J%=INSTR(I%,L$,"4.. }")
870    IF J%=0 THEN 900
880    L$=MID$(L$,1,I%-1)+MID$(L$,I%+14,J%-I%-14)+"2."+MID$(L$,J%+5)
890    GOTO 840 
900   I%=INSTR(1,L$,"\times 16/7 { ")
910   IF I%=0 THEN 960 
920    J%=INSTR(I%,L$,"4.. }")
930    IF J%=0 THEN 960
940    L$=MID$(L$,1,I%-1)+MID$(L$,I%+14,J%-I%-14)+"1"+MID$(L$,J%+5)
950    GOTO 900 
960   REM ***** remove excess \times (triplets) *****
970   P%=INSTR(1,L$,"} \times 2/3 {") 
980   IF P%=0 THEN 1010  :REM none left
990    L$=MID$(L$,1,P%-1)+MID$(L$,P%+14)
1000    GOTO 960  :REM check for more
1010   REM ***** remove repetitive durations *****
1020   J%=0: D0$=""
1030   FOR I%=1 TO LEN(L$)
1040    C%=ASC(MID$(L$,I%,1))
1050    IF C%=42 THEN 1150       :REM * irregular 
1060     IF C%=32 THEN 1100       :REM space end of word
1070      IF C%<48 OR C%>57 THEN 1140   :REM not numeric
1080       IF J%=0 THEN J%=I%    :REM start of numeric
1090        GOTO 1140
1100    IF J%=0 THEN 1140         :REM no duration
1110    D$=MID$(L$,J%,I%-J%)     :REM this duration
1120   IF D$<>D0$ THEN D0$=D$: J%=0: GOTO 1140 :REM different from previous
1130    L$=MID$(L$,1,J%-1)+MID$(L$,I%): J%=0: GOTO 1010 :REM same, remove it
1140   NEXT I%
1150  REM ***** output *****
1160  PRINT#2,L$
1170  GOTO 80
1180 REM ***** all done *****
1190 CLOSE
1200 END

10 REM LILYCLN: global cleanup of Lily files
20 FOR K%=1 TO 555
30  FOR J%=0 TO 4
40   IF J%=0 THEN J$="" ELSE J$=MID$("abcd",J%,1)
50   F$="K"+MID$(STR$(1000+K%),3)+J$+".ly"
60   ON ERROR GOTO 80
70   OPEN F$ FOR INPUT AS 1: GOTO 90
80    RESUME 570
90   REM file exists
100  ON ERROR GOTO 0
110  PRINT K%;J$;
120  V%=96: T%=96 :REM base of lower case letters
130  L%=0         :REM line#
140  T0%=0        :REM thread indent
150  OPEN "lilyedit.tmp" FOR OUTPUT AS 2
160  IF EOF(1) THEN 540 :REM read all of file
170   LINE INPUT#1,L$: L%=L%+1
180   IF L%=1 AND MID$(L$,1,1)="%" THEN L$="%"+F$+" LilyPond 1.2.16"
190   REM get rid of waste spaces
200   IF LEN(L$)=0 THEN 160  :REM null line
210   IF ASC(L$)=32 THEN L$=MID$(L$,2): GOTO 200 :REM leading space
220   I%=LEN(L$) :REM trailing space
230   IF MID$(L$,I%)=" " THEN L$=MID$(L$,1,I%-1): GOTO 200
240   I%=INSTR(1,L$,"  ")  :REM multiple space
250   IF I%>0 THEN L$=MID$(L$,1,I%)+MID$(L$,I%+2): GOTO 240
260   D0$="<>[]{}^~|=%"  :REM delimiter list
270   FOR D%=1 TO LEN(D0$)
280    D$=MID$(D0$,D%,1)
290    I%=INSTR(1,L$,D$+" ")
300    IF I%>0 THEN L$=MID$(L$,1,I%)+MID$(L$,I%+2): GOTO 290
310    I%=INSTR(1,L$," "+D$) 
320    IF I%>0 THEN L$=MID$(L$,1,I%-1)+MID$(L$,I%+1): GOTO 310
330   NEXT D%
340   REM sequence voices va-vz and threads ta-tz
350   I%=INSTR(1,L$,"Voice="): IF I%=0 THEN 390
360    C%=INSTR(I%,L$,"<"): IF C%<I% THEN 390
370    V%=V%+1: T0%=-1
380    L$=MID$(L$,1,I%+5)+"v"+CHR$(V%)+"< \zs"
390   IF INSTR(1,L$,"autochange")>0 THEN T0%=-1 :REM end of thread
400   IF INSTR(1,L$,"Staff=")>0 THEN T0%=-1 :REM end of last thread
410   I%=INSTR(1,L$,"Thread="): IF I%=0 THEN 450
420    C%=INSTR(I%,L$,"{"): IF C%<I% THEN 450
430    T%=T%+1: T0%=T0%+1
440    L$=MID$(L$,1,I%+6)+"t"+CHR$(T%)+"{ \n"
450   REM add voice ident to bar numbers
460   IF L%=1 OR MID$(L$,1,1)<>"%" THEN 490
470    IF ASC(MID$(L$,2))>64 THEN L$="%"+MID$(L$,3): GOTO 470
480    L$="%"+CHR$(V%)+MID$(L$,2)
490   REM add thread-in-voice level indent
500   IF T0%<0 THEN B%=0 ELSE B%=T0%
510   REM output
520   PRINT#2,SPACE$(B%)+L$
530   GOTO 160
540  CLOSE
550  KILL F$
560  NAME "lilyedit.tmp" AS F$
570 NEXT J%
580 NEXT K%
590 END

%TeX envelope
%PostScript measures from the bottom of a page, TeX from the top so for PS printing
%  on both letter and A4 paper, you have to use letterpaper with text limited to A4 width.
\documentclass[11pt]{article}
\usepackage{times}
\usepackage[letterpaper,dvips,left=11mm,width=188mm,top=-6mm, height=278mm,includemp=false]{geometry}
\usepackage[latin1]{inputenc} 
\input lilyponddefs
\def\interscoreline{\vskip 8pt}
\renewcommand \thepage{{1-\arabic{page}}}
\begin{document}
\begin{center}
 \Huge{Sonata}
\end{center}
\vspace{-9mm}
\large
\begin{flushright}
{\scshape Domenico Scarlatti\\K.1 L.366}
\end{flushright}
\vspace{1mm}
Allegro
\vspace{-4mm}
\input{K001.tex}
\footnotesize
\vspace{5mm} \noindent
\copyright John Sankey 1999.
\end{document}

%bash script
cp -f /mnt/msdos/linux/T$1.tex .
cp -f /mnt/msdos/linux/K$1.ly .
lilypond K$1&>/mnt/msdos/linux/K$1.log
latex T$1
dvips T$1 -oK$1.ps
mv -f K$1.ps /mnt/msdos/linux
rm -f K$1.tex
rm -f T$1.dvi
rm -f T$1.aux
rm -f T$1.log
rm -f T$1.tex
rm -f K$1.ly

%K001.ly LilyPond 1.2.16
\include "jdsprop.ly";
\score{
\context PianoStaff \notes<
\context Staff=up<
\time 4/4;
\keysignature bes;
\clef treble;
\autochange Staff
\context Voice=va< \zs
\su
\context Thread=ta{ \n
%a1
\rh[d''16 e'' f'' g''][a'' a' cis'' a']d''4. e''8|
%a2
[f''16 d'' g'' e''][a'' f'' e'' d''][cis''8 a'']a''4^\prall~
%a3
[a''16 g'' f'' e''][d'' c'' bes' a'][bes'8 \lh g'']g''4^\prall~
%a4
[g''16 f'' e'' d''][c'' bes' \rh a' g'][a'8 f'']f''4^\prall~
%a5
[f''16 e'' d'' c''][bes' a' g' f'][g'8 \lh e'']e''4^\prall~
%a6
[e''16 d'' cis'' b'][a' g' \rh f' e'][f' d' g' e'][a' f' e' d']|
%a7
[cis'16 a d' b][e' cis' f' d'][g' e' a' f'][b' g' cis'' a']|
%a8
[d''16 b' e'' cis''][f'' d'' g'' e'']a''4 g''^\prall|
%a9
\lh a''4 g''^\prall \rh a'' g''^\prall|
%a10
[f''16 d'' g'' e''][a'' f'' e'' d''][cis'' a' d'' b'][e'' g' f' e']|
%a11
[f'16 d' g' e'][a' f' e' d'][cis' a d' b][e' cis' f' d']|
%a12
[g'16 g' f' e'][f'8 g'16^\prall f'32 g'][a'16 e' f' d'][e' cis' \lh f'8]|
%a13
[e'8 d']cis'16 s8. s2 \bar "||";
%a14
\rh[a'16 b' cis'' d''][e'' cis'' f'' d'']e''4. a'8|
%a15
[b'16 g' cis'' a'][d'' b' e'' cis''][fis'' d'' g'' e''][a'' c'' bes' a']|
%a16
[bes'16 g' c'' a'][d'' bes' a' g'][fis' d' g' e'][a' c' bes a]|
%a17
\lh[bes16 g c' a][d' bes e' c'][f' d' g' e'][a' f' \rh bes' \lh g']|
%a18
\rh c''4 bes'^\prall \lh c'' bes'^\prall|
%a19
\rh[c''8 f''][bes' e''][a'16 f' c'' a'][f'' c'' a'' f'']|
%a20
[e''16 g'' c'' e''][g' \lh c'' bes' a'][bes' g' d'' bes'][g'' d'' bes'' g'']|
%a21
[f''16 a'' d'' f''][a' d'' c'' b']\rh[c'' a' e'' c''][a'' e'' c''' a'']|
%a22
[gis''16 b'' e'' gis''][b' d'' cis'' b'][cis''8 a'']a''4^\prall^"\\textflat"~
%a23
[a''16 g'' f'' e''][d'' c'' \lh bes' a'][bes'8 \rh g'']g''4^\prall~
%a24
[g''16 f'' e'' d''][c'' bes' \lh a' g'][a'8 \rh f'']f''4^\prall~
%a25
[f''16 e'' d'' c''][bes' a' \lh g' f'][g'8 \rh e'']e''4^\prall~
%a26
[e''16 d'' cis'' b'][a' g' f' e'][f' d' g' e'][a' f' bes' g']|
%a27
[f'16 d' g' e'][a' f' bes' g']\lh[f' d' g' e'][a' f' bes' g']|
%a28
\rh[a'8 d''][g' cis''][\lh a' \rh f''][\lh g' \rh e'']|
%a29
[a'8 d''][g' e''][f'16 d' g'16 e'][a' f' b' g']|
%a30
[cis''16 a' d'' e''][f'' d'' e'' cis''][d'' a' bes' g'][a' f' \lh bes'8]|
%a31
[a'8 g']f'16 s8. s2 \bar "|.";
}
 \context Thread=tb{ \n
 \lh s1*9|
 %a10
 d''16 s4.. a'16 s4..|
 %a11
 d'16 s2...|
 s1*3|
 %a15
 s2 d''16 s4..|
 %a16
 g'16 s4.. d'16 s4..|
 s1*2|
 %a19
 s8 \rh a'' s g'' s2|
 s1*8
 %a28
 s8 f'' s e'' s d'' s cis''|
 %a29
 s8 f'' s cis''
 }>
\autochange Staff
\context Voice=vb< \zs
\sd
\context Thread=tc{ \n
%b1
\lh s2[d'16 e' f' g'][a' a cis' a]|
%b2
[d'8 e' f' g'][a' a' a' a']|
%b3
[a'8 a' a' f'][g \rh bes' bes' bes']|
%b4
[g'8 g' g' e'][\lh f a' f' a']|
%b5
[d'8 f' d' d'][e \rh g' g' g']|
%b6
[a8 a a a][\lh d e f g]|
%b7
a8 s[cis' d'][e' f'][g' a']|
%b8
[b'8 cis''][d'' e''][f''16 d'' bes' g'][e'' cis'' a' \rh cis'']|
%b9
[f''16 d'' bes' g'][e'' cis'' a' cis'']\lh[f'' d'' bes' g'][e'' cis'' a' cis'']|
%b10
[d'8 e' f' g'][a b cis' a]|
%b11
[d8 e f g][a b][cis' d']|
%b12
[e16 e' d' cis'][d'8 bes]\su a,4 \sd s8 \rh[d'16 b]|
%b13
[cis'16 a b gis][a16 e cis e]\lh \su a,4^\prall^"\\textnatural" r^\fermata|
%b14
\sd s2[a16 b cis' d'][e' cis' f' d']|
%b15
[g'8 a'][b' cis''][d' e' fis' d']|
%b16
[g8 a bes c'][d e fis d]|
%b17
\rh[g8 a][bes c'][d' e'][f' g']|
%b18
\lh[a'16 f' d' bes][g' e' c' \rh e'][a' f' d' bes][g' e' c' e']|
%b19
\lh[a'16 f' d' bes][g' e' c' e'][f'8 \su f f f,]|
%b20
[c8 c' c' \rh \sd fis'][g' \su g g g,]|
%b21
[d8 \sd d' d' gis']\lh[a' \su a a a,]|
%b22
[e8 e, e, e,][a, \sd a' a' a']|
%b23
[\su f,8 \sd a' a' f'][\rh \su g, \lh \sd bes' bes' bes']|
%b24
[\su e,8 \sd e' g' e'][\su \rh f, \sd \lh a' a' a']|
%b25
[\su d,8 \sd f' f' d'][\su \rh e, \sd \lh g' g' g']|
%b26
[a,8 a a a][d' e'][f' g']|
%b27
\rh[d'8 e'][f' g']\lh[d' e'][f' g']|
%b28
[f'16 d' bes g][e' cis' a cis'][f' d' bes g][e' cis' a cis']|
%b29
[\rh f'16 \lh d' bes g][\rh e' \lh cis' a cis'][d8 e][f g]|
%b30
[a8 g a a,]\su d4 \sd s8 \rh[g'16 e']|
%b31
[f'16 d' e' cis'][d'16 a f a]\lh \su d4^\prall r4^\fermata|
}
 \context Thread=td{ \n
 s1*2|
 %b3
 \lh f'8 f' f' s4 \rh g'8 g' g'|
 %b4
 e'8 e' e' s4 \lh f'8 a' f'|
 %b5
 f'8 d' f' s4 \rh e'8 e' e'|
 s1*17|
 %b23
 \lh s8 f' f' s4 g'8 g' g'|
 %b24
 s8 g' e' s4 f'8 f' f'|
 %b25
 s8 d' d' s4 e'8 e' e'
 }>
\autochange Staff
\context Voice=vc< \zs
\sd
\context Thread=te{ \n
s1*5|
%c6
\rh e'8 e' e' s d' s4.|
s1*19
%c26
\lh s8 e' e' s \sls \rh \su d''4 s|
%c27
\lh d''4 s \rh d''4 \zs s|
s1
%c29
\sd s2 \lh d'8
}>>
\context Staff=down<
\keysignature bes;
\clef bass;
s1*31
>>
\paper{\include "jdspaper.ly";
\translator{\VoiceContext \remove Auto_beam_engraver;}
}}

See the results