Hi everybody!

To generate score videos like Bach: Invention 1 
<https://www.youtube.com/watch?v=EqWYmrwTcqQ>, Wolf: Resignation 
<https://www.youtube.com/watch?v=IonPmbdY7ME> and Peterson-Berger: I Fyrreskoven 
<https://www.youtube.com/watch?v=hgDWprKiyo0>
that give a different color to notes and rest while they are active you might 
use the attached files if
you run a unixoid system like linux.

mkvideo-lily-diff contains changes to an installed version of lilypond (tested 
with 2.19.65, but it also
should work with much older versions). No recompilation is necessary, only scm 
and ps files are
changed. The patched version of lilypond will behave exactly like the unpatched 
version as long as
videohelper.ily is not used. One exception: If you define illegal rgb colors 
(R,G,B not in the range
[0.0 ... 1.0]) this will not be detected.

Wolf_Resignation.ly is a lilypond score that demonstrates the intended use. Be 
sure to have a close
look at the comments!

videohelper.ily includes some definitions needed for video generation.

mkvideo requires bash, ls, sort, tail, uniq, grep, sed, usleep, bc, gs, pdftk,
lilypond, fluidsynth, sox, ffmpeg, wc and a suitable sound font, e.g. 
FluidR3_GM.sf2

1. Patch some of the scm and ps files of your version of lilypond. Adapt the 
paths first!

   cd /some/path/lilypond/2.19.65
   patch -p 1 < /some/path/mkvideo-lily-diff

2. Store the other files in a separate directory and feed lilypond:

   lilypond Wolf_Resignation

3. Run the mkvideo script:

   ./mkvideo

At the top of mkvideo there are some definitions that might be changed ... be 
sure to define a
suitable soundfont.

If you have problems: DEBUG gives a very verbose output, clean keeps temporary 
files.

cu,
 Knut
diff -U 4 ./origscm/framework-ps.scm ./scm/framework-ps.scm
--- ./origscm/framework-ps.scm  2016-11-21 05:26:10.890701666 +0100
+++ ./scm/framework-ps.scm      2017-07-20 06:43:33.177169912 +0200
@@ -108,9 +108,14 @@
    (output-entry "page-width" 'paper-width)
    (if (ly:get-option 'strokeadjust) "true setstrokeadjust\n" "")
    ))
 
+;; [mkvideo] This version of dump-page is extended for mkvideo.
+;; As long as null? videopagelist is true nothing changes.
 (define (dump-page outputter page page-number page-count landscape?)
+  (let* (
+    (ml (assoc page-number videopagelist))
+    (rep? (and (not (null? videopagelist)) (if (pair? ml) (not (null? (cdr 
ml))) #f))))
   (ly:outputter-dump-string
    outputter
    (string-append
     (format #f "%%Page: ~a ~a\n" page-number page-number)
@@ -119,8 +124,9 @@
         "page-width output-scale lily-output-units mul mul 0 translate 90 
rotate\n"
         "")
     "%%EndPageSetup\n"
     "\n"
+    (format #f (if rep? "/lilypage {\n" ""))
     "gsave 0 paper-height translate set-ps-scale-to-lily-scale\n"
     "/helpEmmentaler-Brace where {pop helpEmmentaler-Brace} if\n"
     "/helpEmmentaler-11 where {pop helpEmmentaler-11} if\n"
     "/helpEmmentaler-13 where {pop helpEmmentaler-13} if\n"
@@ -130,9 +136,15 @@
     "/helpEmmentaler-20 where {pop helpEmmentaler-20} if\n"
     "/helpEmmentaler-23 where {pop helpEmmentaler-23} if\n"
     "/helpEmmentaler-26 where {pop helpEmmentaler-26} if\n"))
   (ly:outputter-dump-stencil outputter page)
-  (ly:outputter-dump-string outputter "stroke grestore\nshowpage\n"))
+  (ly:outputter-dump-string outputter "stroke grestore\nshowpage\n")
+  (if rep? (list
+    (ly:outputter-dump-string outputter (format #f "} def 1 "))
+    (do ((i 0 (1+ i)))
+      ((>= i (length (cdr ml))))
+      (ly:outputter-dump-string outputter (format #f "~a " (list-ref (cdr ml) 
i))))
+    (ly:outputter-dump-string outputter (format #f " { /MkVidTime exch def 
MkVidTime 1 eq { exit } if lilypage } loop\n" ))))))
 
 (define (supplies-or-needs paper load-fonts?)
   (define (extract-names font)
     (if (ly:pango-font? font)
diff -U 4 ./origscm/output-lib.scm ./scm/output-lib.scm
--- ./origscm/output-lib.scm    2017-02-03 06:54:22.841211149 +0100
+++ ./scm/output-lib.scm        2017-07-20 06:34:08.286750353 +0200
@@ -703,13 +703,14 @@
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;; Color
 
+;; [mkvideo] This version of color? does _not_ check that
+;; r, g and b are in the range [0.0 .. 1.0]!
 (define-public (color? x)
   (and (list? x)
        (= 3 (length x))
-       (every number? x)
-       (every (lambda (y) (<= 0 y 1)) x)))
+       (every number? x)))
 
 (define-public (rgb-color r g b) (list r g b))
 
 ;; predefined colors
diff -U 4 ./origscm/output-ps.scm ./scm/output-ps.scm
--- ./origscm/output-ps.scm     2016-11-21 05:26:10.894702197 +0100
+++ ./scm/output-ps.scm 2017-07-20 06:35:48.233783884 +0200
@@ -204,10 +204,11 @@
     (ly:format  "~4l draw_round_box"
                 (list width height x y blotdiam))))
 
 ;; save current color on stack and set new color
+;; [mkvideo] This version of setcolor extends the precision
 (define (setcolor r g b)
-  (ly:format "gsave ~4l setrgbcolor\n"
+  (ly:format "gsave ~9l setrgbcolor\n"
              (list r g b)))
 
 ;; restore color from stack
 (define (resetcolor) "grestore\n")
diff -U 4 ./origscm/paper.scm ./scm/paper.scm
--- ./origscm/paper.scm 2016-11-21 05:26:10.898702727 +0100
+++ ./scm/paper.scm     2017-07-14 09:51:45.322354046 +0200
@@ -17,8 +17,10 @@
 
 ;; for define-safe-public when byte-compiling using Guile V2
 (use-modules (scm safe-utility-defs))
 
+(define-public videopagelist '())
+
 (define-public (set-paper-dimension-variables mod)
   (module-define! mod 'dimension-variables
                   '(binding-offset
                     blot-diameter
diff -U 4 ./origps/music-drawing-routines.ps ./ps/music-drawing-routines.ps
--- ./origps/music-drawing-routines.ps  2016-05-22 19:27:33.908557943 +0200
+++ ./ps/music-drawing-routines.ps      2017-07-20 06:21:39.838577836 +0200
@@ -307,5 +307,33 @@
                moveto %w
                0 rmoveto
        }repeat
 }bind def
+
+/MKVIDcolor { 0.7 0.0 1.0 } def             % color to use
+                                            %
+/MKVIDmagic { 2.0 } def                     % magic value for our own coloring 
requests
+                                            %
+/MKVIDsetrgbcolor {                         % the extended setrgbcolor
+  3 dict begin                              % start local name space
+  /Stop exch def                            % local "blue": stop
+  /Start exch def                           % local "green": start
+  /Red exch def                             % local "red": magic
+  Red MKVIDmagic eq                         % if (Red = MKVIDmagic) (
+     { Start MkVidTime eq                   %   if (start = current time)
+        { MKVIDcolor ORIGsetrgbcolor}       %     change color to red
+        { Start MkVidTime gt                %   else if ((start > current time)
+          { Stop MkVidTime lt               %      and (stop < current time))
+            { MKVIDcolor ORIGsetrgbcolor }  %        change color to red
+          if }                              %   else
+        if }                                %      do not change color
+     ifelse }                               %
+     { Red Start Stop ORIGsetrgbcolor }     % ) else change color as requested
+     ifelse                                 %
+  end                                       % stop local namespace
+} def                                       %
+                                            %
+/ORIGsetrgbcolor /setrgbcolor load def      % make original setrgbcolor 
available as /ORIGsetrgbcolor
+                                            %
+/setrgbcolor { MKVIDsetrgbcolor } bind def  % redefine setrgbcolor
+
 %end music-drawing-routines.ps
#(define mkvid_out (open-output-file "videohelper.notes"))

#(format mkvid_out "~a~a~a" "LILYSOURCE=" (ly:parser-output-name) ".ly\n")

pdfforvideo       = #(define-void-function () () (format mkvid_out "~a~a~a" 
"VIDEOSOURCE=" current-outfile-name ".pdf\n"))
midiforvideo      = #(define-void-function () () (format mkvid_out "~a~a~a" 
"MIDISOURCE=" current-outfile-name ".midi\n"))
videoResolution   = #(define-void-function (parser location x y) (number? 
number?) (format mkvid_out "VIDEORESOLUTION=~ax~a\n" x y))
videoPreset       = #(define-void-function (parser location p) (string?) 
(format mkvid_out "PRESET=~a\n" p))
audioBitRate      = #(define-void-function (parser location p) (string?) 
(format mkvid_out "AUDIOBITRATE=~a\n" p))

#(define pagerepetitions? #t)
#(define colorflags? #t)
#(define colorstems? #t)
#(define colordots? #t)
#(define colorheads? #t)

noPageRepetitions = #(define-void-function () () (list (set! pagerepetitions? 
#f) (format mkvid_out "NOPAGEREPETITIONS\n")))
noColorFlags      = #(define-void-function () () (set! colorflags? #f))
noColorStems      = #(define-void-function () () (set! colorstems? #f))
noColorDots       = #(define-void-function () () (set! colordots?  #f))
noColorHeads      = #(define-void-function () () (set! colorheads? #f))

#(define (format-moment moment)
   (exact->inexact
    (/ (ly:moment-main-numerator moment)
       (ly:moment-main-denominator moment))))

#(define tempolist '())

#(define (format-tempo engraver event)
    (let* (
        (metrocount (ly:event-property event 'metronome-count))
        (tempounit  (ly:event-property event 'tempo-unit))
        (seconds    (/ 60 (* metrocount (format-moment (ly:duration-length 
tempounit)))))
        (time       (ly:context-current-moment (ly:translator-context 
engraver)))
        (moment     (+ 0.0 (ly:moment-main time) (* (ly:moment-grace time) (/ 9 
40)))))
   (if metrocount
       (format mkvid_out "~a tempo ~f\n" moment seconds))))

#(define (format-time engraver event)
    (let* (
        (numerator   (ly:event-property event 'numerator))
        (denominator (ly:event-property event 'denominator))
        (time        (ly:context-current-moment (ly:translator-context 
engraver)))
        (moment      (+ 0.0 (ly:moment-main time) (* (ly:moment-grace time) (/ 
9 40)))))
    (format mkvid_out "~a time ~a ~a\n" moment numerator denominator)))

\layout { 
    \context { \Staff 
        \consists #(make-engraver (listeners (time-signature-event . 
format-time))) }
    \context { \Voice 
        \consists #(make-engraver (listeners (tempo-change-event . 
format-tempo))) }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Color notes and rests
%

#(define (grob-get-ancestor-with-interface grob interface axis)
    (let ((parent (ly:grob-parent grob axis)))
    (if (null? parent)
        #f
        (if (grob::has-interface parent interface)
            parent
            (grob-get-ancestor-with-interface parent interface axis)))))

#(define (grob-get-paper-column grob)
    (grob-get-ancestor-with-interface grob 'paper-column-interface X))

#(define (pitch-to-string p)
    (let* (
        (nn          (ly:pitch-notename p))
        (nn-string   (list-ref '("c" "d" "e" "f" "g" "a" "h") nn))
        (alt         (ly:pitch-alteration p))
        (alt-num     (+ 2 (* 2 alt)))
        (alt-string  (list-ref '("eses" "es" "" "is" "isis") alt-num))
        (oct         (ly:pitch-octave p))
        (oct-num     (+ 5 oct))
        (oct-string  (list-ref '(",,,," ",,," ",," "," "" "'" "''" "'''" "''''" 
"'''''" "''''''") oct-num))
        (na          (cons nn alt))
        (test        (lambda (n a) (equal? na (cons n a))))
        (na-string (cond
             ((test 2 -1) "eses")
             ((test 2 -1/2) "es")
             ((test 5 -1) "asas")
             ((test 5 -1/2) "as")
             ((test 6 -1/2) "b")
             (else (string-append nn-string alt-string)))))
    (string-append na-string oct-string)))


#(define maxstop 0.0)               % maximum Moment
#(define startlist '())             % Liste aller Startmomente von Noten oder 
Pausen
#(define firstmomentlist '())       % Liste aller ersten Momente jeder Seite

#(define (mkvideo-dump grob)
    (let* (
        (pap          (ly:parser-lookup '$defaultpaper))
        (paper-column (grob-get-paper-column grob))
        (cause        (ly:grob-property grob 'cause))
        (pitch        (if (ly:prob? cause) (ly:event-property cause 'pitch)))
        (lilypitch    (if (ly:pitch? pitch) (pitch-to-string pitch) "NaP"))
        (type         (if (ly:pitch? pitch) "note" "rest"))
        (time         (ly:grob-property paper-column 'when 0))
        (start        (+ 0.0 (ly:moment-main time) (* (ly:moment-grace time) (/ 
9 40))))
        (duration     (if (ly:prob? cause) (format-moment (ly:duration-length 
(ly:event-property cause 'duration))) 0.0))
        (stop         (+ start duration))
        (nstart       (- 0 start))
        (nstop        (- 0 stop))
        (stem         (ly:grob-object grob 'stem))
        (flag         (ly:grob-object grob 'flag))
        (dot          (ly:grob-object grob 'dot))
        (R            (if pagerepetitions? 2.0    0.6))
        (G            (if pagerepetitions? nstart 0.0))
        (B            (if pagerepetitions? nstop  1.0)))
    (if (not (equal? (ly:grob-property grob 'transparent) #t))
        (format mkvid_out "~f ~a ~f ~a\n" start type stop lilypitch))
    (if (equal? (member nstart startlist) #f)
        ( list
          (set! startlist (append startlist (list nstart)))
          (set! startlist (sort-list startlist >=))))
    (if (> maxstop nstop)
        (set! maxstop nstop))
    (list
        (if colorheads?
            (ly:grob-set-property! grob 'color (rgb-color R G B)))
        (if (and (not (null? stem)) colorstems?)
            (ly:grob-set-property! stem 'color (rgb-color R G B)))
        (if (and (not (null? flag)) colorflags?)
            (ly:grob-set-property! flag 'color (rgb-color R G B)))
        (if (and (not (null? dot)) colordots?)
            (ly:grob-set-property! dot 'color (rgb-color R G B))))))

\layout {
    \context { \Voice
        \override NoteHead #'after-line-breaking = #mkvideo-dump
        \override Rest #'after-line-breaking = #mkvideo-dump
        \override MultiMeasureRest #'after-line-breaking = #mkvideo-dump
        \override NoteHead.layer = 3
    }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Here we do some post-processing and build the alist for the page dumper
% (key is the page number, value is the list of moments on the page)
%

#(define dumpedstartlist? #f)

#(define (dumpstartlist)
    (list
        (do ((i 0 (1+ i)))
            ((>= i (length startlist)))
            ( format mkvid_out "~a page\n" (- 0 (list-ref startlist i))))
        (format mkvid_out "LASTMOMENT=~a\n"  (- 0 maxstop))
        (set! dumpedstartlist? #t)))
    
    
#(define (after-pb-processing layout pages)
  (let* (
    (lines        (map
                    (lambda (page)
                      (ly:prob-property page 'lines))
                  pages))
    (systems      (map
                    (lambda (line)
                      (append-map
                        (lambda (l)
                          (let (
                            (system-grob (ly:prob-property l 'system-grob)))
                        (if (not (null? system-grob)) 
                          (list system-grob) system-grob)))
                      line))
                  lines))
    (firstmoments (append
                    (map 
                      (lambda (m) 
                        (if (and (not (null? m)) (ly:grob? (car m)))
                          (- 0 (format-moment (grob::when (car m))))
                          #f))
                    systems)
                  (list maxstop)))
    (moments      (append startlist (list maxstop))))
  (if (and (not (null? firstmoments)) pagerepetitions?)
    (map 
      (lambda (page m) 
        (if m
          (set! videopagelist (acons page (cdr (member (list-ref firstmoments 
page) (reverse (member m moments)))) videopagelist))
          (list
            (if (not dumpedstartlist?)
              (dumpstartlist))
            (set! videopagelist (acons page '() videopagelist ))
            (format mkvid_out "page ~a contains no music\n" page)
          )
        )
      )
    (iota (length pages) 1 1) 
    firstmoments))))

\paper {
        #(define (page-post-process layout pages) (after-pb-processing layout 
pages))
}
#!/bin/bash

######################################################################
# Copyright (C) 2016-2017 Knut Petersen (knut_peter...@t-online.de)
#
# This is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# 
# This file is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
######################################################################


VERSION=2017-07-21
# FPS=n: video files will use n frames per second
#  Currently FSP != 25 is broken. It's either ffmpeg or I am too
#  blind to see my mistake ;-(
FPS=25
VIDEORESOLUTION=1280x720
PRESET=veryslow
AUDIOBITRATE=128k
# TITLETIME: number of seconds the title page shall be visible
TITLETIME=4.0
# AFTERTIME
AFTERTIME=6.666
# DEBUG: n != 0 turns on debugging mode (verbose output)
DEBUG=0
# CLEAN: n != 0 enables deletion of all temporary files
CLEAN=1
#
SOUNDFONTB=./kptestpiano.sf2
SOUNDFONTA=/usr/share/sounds/sf2/FluidR3_GM.sf2
SOUNDFONTS="$SOUNDFONTA $SOUNDFONTB"

FAIL=0

function weneedprog {
 for P in $@; do
   TMP=`which $P 2> /dev/null`
   if [ "x" == "x$TMP"  ]; then
      echo We need $P but could not find it!
      FAIL=$((FAIL+1))
   fi
 done
}

function weneeddata {
 for P in $@; do
   TMP=`ls -q $P 2> /dev/null`
   if [ "x" == "x$TMP"  ]; then
      echo We need $P but could not find it!
      FAIL=$((FAIL+1))
   fi
 done
}

echo This is mkvideo version $VERSION
echo checking dependencies ...
weneedprog ls sort tail uniq grep sed usleep bc gs pdftk lilypond fluidsynth 
sox ffmpeg
weneeddata $SOUNDFONTS videohelper.notes
if [ $FAIL -ne 0 ]; then
  echo $FAIL missing dependencies, aborting
  exit 1
else
  echo dependencies ok
fi

function checknotes {
  grep "$1" videohelper.notes &> /dev/null
  if [ $? -ne 0 ]; then
     echo Fatal error: $2
     exit 2
  fi
}

grep "NOPAGEREPETITIONS" videohelper.notes  &> /dev/null
if [ $? -eq 0 ]; then
    echo "No video generation because \noPageRepetitions was used!"
    exit
fi

echo checking videohelper.notes ...
checknotes "LILYSOURCE" "LILYSOURCE undefined"
checknotes "VIDEOSOURCE" "VIDEOSOURCE undefined"
checknotes "MIDISOURCE" "MIDISOURCE undefined"
checknotes "tempo" "no tempo definition"
checknotes "time" "no time definition"
checknotes "page 1 contains no music" "no title page defined"
checknotes "[0-9.]* page" "not a single page"
echo videohelper.notes ok

TDIR=`mktemp -d mkvideo-XXXXX`

eval `grep LILYSOURCE videohelper.notes`
eval `grep VIDEOSOURCE videohelper.notes`
eval `grep LASTMOMENT videohelper.notes`

grep VIDEORESOLUTION videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
  eval `grep VIDEORESOLUTION videohelper.notes`
fi

grep PRESET videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
  eval `grep PRESET videohelper.notes`
fi

grep AUDIOBITRATE videohelper.notes &> /dev/null
if [ $? -eq 0 ]; then
  eval `grep AUDIOBITRATE videohelper.notes`
fi

MIDILIST=`grep MIDISOURCE videohelper.notes | sed -e 
"s/MIDISOURCE=\([[:print:]]*\).midi/\1/" | sort | uniq | sed ':a;N;$!ba;s/\n/ 
/g'`

MOMENTLIST="`grep "[0-9.]* page" videohelper.notes | sed -e 
"s/\([0-9.]*\)[[:space:]][[:print:]]*/\1/" | sed ':a;N;$!ba;s/\n/ /g'` 
$LASTMOMENT"
COUNT=1
ARMOM=()
for VAL in $MOMENTLIST; do
    ARMOM[COUNT]=$VAL
    COUNT=$((COUNT+1))
done
if [ $DEBUG -ne 0 ] ; then
   declare -p ARMOM
fi

TEMPOMOMENTLIST=`grep tempo videohelper.notes | sed -e 
"s/\([0-9.]*\)[[:space:]]tempo[[:space:]]\([0-9.]*\)/\1 /" | sed 
':a;N;$!ba;s/\n/ /g'`
COUNT=1
TMMOM=()
for VAL in $TEMPOMOMENTLIST; do
    TMMOM[COUNT]=$VAL
    COUNT=$((COUNT+1))
done
TMMOM[COUNT]=100000.0
if [ $DEBUG -ne 0 ] ; then
    declare -p TMMOM
fi

TEMPOTIMELIST=`grep tempo videohelper.notes | sed -e 
"s/\([0-9.]*\)[[:space:]]tempo[[:space:]]\([0-9.]*\)/\2 /" | sed 
':a;N;$!ba;s/\n/ /g'`
COUNT=1
TTMOM=()
for VAL in $TEMPOTIMELIST; do
    TTMOM[COUNT]=$VAL
    COUNT=$((COUNT+1))
done
TTMOM[COUNT]=0.0
if [ $DEBUG -ne 0 ] ; then
    declare -p TTMOM
fi

TEMPOS=`grep tempo videohelper.notes | wc | sed -e 
"s/[[:space:]]*\([[:digit:]]*\)[[:print:]]*/\1/"`
if [ $DEBUG -ne 0 ] ; then
    echo TEMPOS $TEMPOS
fi

PAGES=`grep page videohelper.notes | wc | sed -e 
"s/[[:space:]]*\([[:digit:]]*\)[[:print:]]*/\1/"`
PAGES=$((PAGES-1))
if [ $DEBUG -ne 0 ] ; then
    echo PAGES $PAGES
fi

MOMENTS=$((PAGES+1))
if [ $DEBUG -ne 0 ] ; then
    echo MOMENTS $MOMENTS
fi

for M in `seq 1 $MOMENTS`;
    do ARTIMES[M]=0.0
done

for T in `seq 1 $TEMPOS`; do
    for M in `seq 1 $MOMENTS`; do
        if (( $(echo "${ARMOM[$M]} > ${TMMOM[$T]}" |bc -l) )); then
            if (( $(echo "${ARMOM[$M]} <= ${TMMOM[$((T+1))]}" |bc -l) )); then
                ARTIMES[$M]=`bc -l 
<<<"${ARTIMES[$M]}+(${ARMOM[$M]}-${TMMOM[$T]})*${TTMOM[$T]}"`
            else
                ARTIMES[$M]=`bc -l 
<<<"${ARTIMES[$M]}+(${TMMOM[$((T+1))]}-${TMMOM[$T]})*${TTMOM[$T]}"`
            fi
        fi
    done
done

for M in `seq 1 $MOMENTS`; do
   ARTIMES[$M]=$(echo $(bc <<< "(${ARTIMES[$M]})*$FPS/1")/$FPS | bc -l)
done

if [ $DEBUG -ne 0 ] ; then
    echo The first page \(title\) will be visible for "$TITLETIME"s.
    echo The last page will be visible for "$AFTERTIME"s after the end of the 
last note/rest.
    for P in `seq 1 $PAGES`; do
            echo "page $((P+1)) from moment ${ARMOM[$P]} to ${ARMOM[$((P+1))]} 
(${ARTIMES[$P]}s to ${ARTIMES[$((P+1))]}s)"
    done
fi

METROTIME=`grep tempo videohelper.notes | sort -n  | head -n 1 | sed -e 
"s/[0-9.]*[[:space:]]tempo[[:space:]]//"`
TIMENUMERATOR=`grep time videohelper.notes | sort -n  | head -n 1 | sed -e 
"s/[0-9.]*[[:space:]]time[[:space:]]\([0-9][0-9]*\)[[:space:]]\([0-9][0-9]*\)/\1/"`
TIMEDENOMINATOR=`grep time videohelper.notes | sort -n  | head -n 1 | sed -e 
"s/[0-9.]*[[:space:]]time[[:space:]]\([0-9][0-9]*\)[[:space:]]\([0-9][0-9]*\)/\2/"`

ARVT[1]=$TITLETIME
for M in `seq 1 $PAGES`;
do
    ARVT[$((M+1))]=`bc <<<${ARTIMES[$((M+1))]}-${ARTIMES[$M]} | sed -r 
's/^(-?)\./\10./'`
done
ARVT[$MOMENTS]=`bc <<<${ARVT[$MOMENTS]}+$AFTERTIME`
ARVT[2]=`bc -l <<<${ARVT[2]}+$METROTIME*$TIMENUMERATOR/$TIMEDENOMINATOR`

if [ $DEBUG -ne 0 ] ; then
    declare -p ARVT
fi

PAGELIST=`grep -o "page [[:digit:]]*" videohelper.notes | sort -n | sed -e 
"s/\(page\) \([[:digit:]]*\)/\1\2/"  | sed ':a;N;$!ba;s/\n/ /g'`

MAXJOBS=2
if [ -e "/proc/cpuinfo" ]; then
    if [ -r "/proc/cpuinfo" ]; then
        MAXJOBS=$((`grep processor /proc/cpuinfo | wc | sed -e 
"s/[[:space:]]*\([[:digit:]]*\)[[:space:]]*[[:print:]]*/\1/"`+1))
    fi
fi
echo we decided to use up to $MAXJOBS parallel jobs ...

function limitjobs {
  while [ `jobs | wc | sed -e 
"s/[[:space:]]*\([[:digit:]]*\)[[:space:]]*[[:print:]]*/\1/"` -ge $MAXJOBS ]; do
    usleep 250
  done
}

echo generating metronome ticks ...
FIRSTTEMPO=`echo 60/$METROTIME*4 | bc -l`
FIRSTTEMPO=`echo $FIRSTTEMPO/1 | bc`
echo "\version \"2.19.55\" \score { \drums { \repeat unfold $TIMENUMERATOR { 
wbl$TIMEDENOMINATOR } } \midi { \tempo 4 = $FIRSTTEMPO } }" > $TDIR/metronome.ly
cd $TDIR
lilypond metronome.ly &> /dev/null &
cd ..

echo generating tsilence.wav ...
sox -n -r 48000 -c 2 -b16 $TDIR/tsilence.wav trim 0.0 $TITLETIME &> 
$TDIR/sox-tsilence.log &

echo generating wav files from midi input ...
for M in $MIDILIST;
do
  limitjobs
  fluidsynth -o synth.sample-rate=48000 -ln --fast-render=$TDIR/$M-tmp1.wav  
$SOUNDFONTS $M.midi &> $TDIR/$M-tmp1.wav.log &
done

echo bursting pdf ...
pdftk $VIDEOSOURCE burst output $TDIR/page%d.pdf


echo synchronizing ...
wait
fluidsynth -o synth.sample-rate=48000 -ln --fast-render=$TDIR/metronome.wav 
$SOUNDFONTS $TDIR/metronome.midi &> $TDIR/metronome.wav.log &

echo "generating `grep page videohelper.notes | wc | sed -e 
"s/[[:space:]]*\([0-9]*\)[[:space:]]*[[:print:]]*/\1/"` temporary h264 files 
... "
for P in `seq 1 $MOMENTS`;
do
    limitjobs
    if [ $DEBUG -ne 0 ] ; then
       echo -n "page$P.h264, length: ${ARVT[$P]}s; "
    else
       echo -n "$P "
    fi
    gs -dBATCH -dNOPAUSE -q -r495.421 -sDEVICE=png256 -sOutputFile=- 
$TDIR/page$((P)).pdf | \
    ffmpeg -y -framerate 1/10000 -i - \
        -vf scale=$VIDEORESOLUTION -c:v libx264 -tune stillimage -preset 
ultrafast \
        -pix_fmt yuv420p -r $FPS -t ${ARVT[$P]} $TDIR/page$((P)).h264 &> 
$TDIR/ffmpeg-page$P.pdf-h264.log &
done
echo
echo synchronizing ...
wait

echo normalizing audio data ...
for M in $MIDILIST;
do
  limitjobs
  sox -v `sox $TDIR/$M-tmp1.wav -n stat -v 2>&1` $TDIR/$M-tmp1.wav 
$TDIR/$M-tmp2.wav &> $TDIR/sox-$M-tmp1-tmp2.log &
done

limitjobs
sox -v `sox $TDIR/metronome.wav -n stat -v 2>&1` $TDIR/metronome.wav 
$TDIR/metronome-norm.wav  &> $TDIR/metronome-norm.wav.log &

echo synchronizing ...
wait

echo adding metronome wav to audio data ...
for M in $MIDILIST;
do
  limitjobs
  sox $TDIR/metronome-norm.wav $TDIR/$M-tmp2.wav $TDIR/$M-tmp3.wav &> 
$TDIR/sox-$M-tmp2-tmp3.log &
done
echo synchronizing ...
wait

echo adding silence to audio data ...
for M in $MIDILIST;
do
  limitjobs
  sox $TDIR/tsilence.wav $TDIR/$M-tmp3.wav $TDIR/$M.wav &> 
$TDIR/sox-$M-tmp2-wav.log &
done
echo synchronizing ...
wait

COUNT=0
for M in $MIDILIST;
do
  echo generating $M.mp4 ...
  if [ $COUNT -eq 0 ]; then
     ls -1 $TDIR/page*.h264 | grep -o  "page[[:print:]]*h264" | sed -e 
"s/page//" | LANG=clang sort -n | sed -e "s/\([[:print:]]*\)/file page\1/" > 
$TDIR/concat.txt
     ffmpeg -y -f concat -i $TDIR/concat.txt  -i $TDIR/$M.wav -c:v libx264 
-tune animation \
            -preset $PRESET -movflags +faststart -bf 2 -flags +cgop -pix_fmt 
yuv420p -r $FPS -c:a aac -b:a $AUDIOBITRATE -shortest $M.mp4 &> 
$TDIR/ffmpeg-$M.mp4.log
     COUNT=$((COUNT+1))
     FIRSTVIDEO=$M.mp4
  else
     limitjobs
     ffmpeg -y -i $FIRSTVIDEO -i $TDIR/$M.wav -c:v copy -map 0:v:0 -map 1:a:0 
-movflags +faststart -c:a aac -b:a $AUDIOBITRATE -shortest $M.mp4 &> 
$TDIR/ffmpeg-$M.mp4.log &
     COUNT=$((COUNT+1))
  fi
done

echo synchronizing ...
wait

echo removing temporary files ...
if [ $CLEAN -eq 1 ]; then
  echo $TDIR | grep "mkvideo-" &> /dev/null
  if [ $? -eq 0 ]; then
    rm -r $TDIR
  fi
fi
%
% Demo for mkvideo
%
% This file defines
%    - an A4 score (four pages)
%    - individual sheets for all voices (one page each)
%
%    - one score to be used for video generation  \   These will be combined
%    - five midi files for video generation       /   to five mp4 videos
%
% Patch your version of lilypond first, then run
%
%     lilypond Wolf_Resignation
%     ./mkvideo
%
% The five videos produced by mkvideo are relatively small (about 4.5M each),
% but a lot of temporary data is written to disk (more than 800M).
%
\version "2.19.65"
\include "deutsch.ly"

#(ly:set-option 'point-and-click #f)

globMus = {
    #(set-accidental-style 'modern-cautionary)
    \autoBeamOff
    \dynamicUp
    \set Score.tempoHideNote = ##t
    \override Hairpin.to-barline = ##t
    \key f \major
    \time 4/4
    \partial 4
}

sopMusic = \relative c'' {
    \set Staff.instrumentName = \markup { \bold "Sopran " }
    c4\p a4. a8 b4\< d\> d\! (c8) b a4 f\pp f f f f
    g4. a8 g4 b a4. e8 cis4 dis e4. (fis8) e4 a4\p a4. a8 g4 g
    fis4. fis8 f4\< b ~ b b8 b des4 des es4. es8 eses4 des des4.\f\> b8 ges4 as
    f2\p ges4 r r2 r4 a8\p\< [(h)]\! c4. c,8\> h4 a'\! a4. gis8 gis4 h8\< [(cis)]
    d4. d8 cis4\> h h4\! (b8) a a4\< as8 [(des)] des4.\mf ces8 b4\> as ges4.\p (f8) es4\! r8^\fermata des8\pp
    des4 ges b8 (ges'4) f8 es4. des8 ces4\< ces ~ ces\> b8 as\! ges4 f
    b4.\> f8\! ges4 ges\pp ges4. ges8 ges4 f f^\markup {\bold\italic "ritardando"} (e8 [f]) e2
    r2 r4^\markup {\bold\italic "a tempo"}  c'4\p a4. a8 b4\< d d\> (c8)\! b a4 f\pp
    f f f f g4. a8 g4 b a4. e8 cis4 dis e4. (fis8) e4 a4\p
    a4. a8 g4\< g b4 (a8) g a2 c4\f c8\< c d4 d d4.\ff d8 e4\> e
    f4.\p e8 e8 [(d)] c4 c4 (b8 [c16 b]) a4 r8 f8\pp f4. f8 c' [(b)] a4 <<g2{s4\<s4\>}>> f4\! \bar "|."
}

altMusic = \relative c' {
    \set Staff.instrumentName = \markup { \bold "Alt " }
    c4\p c8 [(d e)] f b\< [(a)] g\> [(f)] f\! [(e f)] g g [(f)]a,4\pp b a d d
    f8 [(e)] f4 c c cis4. cis8 cis4 h h4. (d8 ~ d [cis]) cis e\p f4. f8 es4 es
    d4. d8 d\< [(es)] e [(f)] ges4 f f fes es4. es8 ges4 ces b4.\f ges8\> es4 es
    es4\p (des8 [ces]) b4\! r r1 r4 dis8\mf (e) fis4.\> fis8 eis4.\p eis8 eis4 fis
    fis\< gis8 [(a)] h4 eis,8 [(fis)] g4\> g g8\< [(fis)] f4 f8\mf [(fes)] es4 d8\> d es f es4\p ( d) es\! r8^\fermata ces8\pp
    b4 des ges ges ges b ces\< fes,8 [(f)] ges4\> f8 [(es)]\! es4 ces
    d\> b\! b f'8\pp [(es)] des4. es8 des4 des c4. (h8) b2
    r2 r4 c4\p c8 [(d e)] f b\< [(a)] g [(f)] f\> [(e f)]\! g g [(f)] a,4\pp
    b a d d f8 [(e)] f4 c4 c cis4. cis8 cis4 h h4. (d8 ~ [d cis]) cis e\p
    f4. f8 f4\< f f e g (f) f\f\< f8 f f4 b h4.\ff g8 gis4\> g
    f4.\p f8 f4 f d (e) g f\pp c (d8) es f4 f f8 [\< (e16 d c8\> b]) a4\! \bar "|."
}

tenMusic = \relative c' {
    \set Staff.instrumentName = \markup { \bold "Tenor " }
    \clef "G_8"
    c4\p c4. c8 f4\< b,\> b\! (g8) e a4 f'8\pp [(e)] e [(d)] d [(c)] c (b4) a8
    c4. h8 b8 [(c)] d [(dis)] fis [(e cis)] a a [(ais h)] a a [(gis16 fis e8 gis]) a4 cis4\p c4. c8 b4 b
    h a gis8\< [(a)] b [(ces)] des4 des ges, ges ges ges heses as8 [(f')] ges4.\f des8\> b4 ces
    as2\p ges4 r r4 fis8\p\< [(gis)] a4 c8 [(h)] a4.\! g8\> fis4 h h\! h8 [(cis)] d4 d
    h4 h gis\< cis8 [(d)] es4\> d cis8\< [(c)] h4 b\mf ces ges2\> (b4\p as) ges r8^\fermata f8\pp
    ges4 b des b ces fes fes8\< [(es)] ces4 es\> d8 [(es)]\! as,4 as
    as4.\> as8\! ges4 ges\pp b4. ges8 b4 b a4 (g) g2
    r2 r4 c4\p c4. c8 f4\< b, b\> (g8)\! e a4 f'8\pp [(e)]
    e [(d)] d [(c)] c (b4) a8 c4. h8 b8 [(c)] d [(dis)] fis [(e cis)] a a [(ais)] h [(a)] a [(gis16 fis e8 gis)] a4\! cis\p
    c4. c8\< d4 h b b a2 a4\f\< a8 a b4 f' g4.\ff h,8 h4\> b
    c4.\p a8 b4 f f (g) e a\pp a4. a8 d4 f, c'\<  (e,)\> f\! \bar "|."
}

basMusic = \relative c' {
    \set Staff.instrumentName = \markup { \bold "Baß " }
    \clef "bass"
    c4\p f,4. es8 d4\< b\> g\! (c8) cis d4  f, \pp g a b h
    c d e r r4 r8 a8 fis4 f e2 a,4 a'4\p f f, g g
    gis (a8) a b8\< [(h16 c)] des4 ges, ges b b ces4 ces c des ges4.\f f8\> es4 ces
    des2\p ges,4 fis8\p [(gis)] a4.\< his8 cis4 dis fis4.\> e8 dis4 h8\< [(cis)] d4\> cis\! h a
    gis fis eis gis a e' es\< d8 [(des)] ges4\mf (ces,2.\> b2\p) ces4 r8^\fermata des8\pp
    ges4 ges ges es ces ges' g\< (as) a4\> b8 ces\! c4 des
    b,\> d\! es ces\pp ges4. ces8 ges4 b f (c'8 [g)] c2
    r2 r4 c'\p f,4. es8 d4\< b g\> (c8)\! cis d4 f,\pp
    g a b h c d e r r4 r8 a8 fis4 f e2 a,4 a\p
    f a h\< d g, c cis d8 [(e)] f4\f\< f b b g4.\ff g8 e4\> c
    a4.\p c8 b4 a g (c) cis d\pp es4 (d8) cis d4 c8 [(a16 b)] <<c2{s4\<s4\>}>> f,4\! \bar "|."
}

lA = \lyricmode { Komm, Trost der Welt, du stil -- le Nacht! Wie steigst du von den Ber -- gen sacht, die Lüf -- te }
lB = \lyricmode { al -- le }
lC = \lyricmode { schla -- fen; 
                  ein Schif -- fer nur noch, wan -- der -- müd', singt ü -- bers Meer sein A -- bend -- lied zu Got -- tes Lob im Ha -- fen.
                  Die Jah -- re wie die Wol -- ken geh'n und las -- sen mich hier ein -- sam steh'n, die Welt hat mich ver -- ges -- sen,
                  da trat'st du wun -- der -- bar zu mir, als ich beim Wal -- des -- rau -- schen hier ge -- dan -- ken -- voll ge -- ses -- sen.
                  O Trost der Welt, du stil -- le Nacht! Der Tag hat mich so müd' ge -- macht, das }
lD = \lyricmode { wei -- te }
lE = \lyricmode { Meer schon dun -- kelt;
                  laß' aus -- ruhn mich von Lust und Not, bis daß das ew' -- ge Mor -- gen -- rot den stil -- len Wald durch -- fun -- kelt,
                  den stil -- len Wald durch -- fun -- kelt. }
satWords = \lyricmode { \lA \lB \lC \lD \lE }
bWords   = \lyricmode { \lA \lC \lE }


%
% Some global definitions for header, paper and layout
%
\header { tagline = ##f }

#(set-global-staff-size 17)

\paper {
    #(set-paper-size "a4")
    left-margin = 2.0\cm
    binding-offset = 0\cm
    line-width = 17\cm
    top-margin = 1.7\cm
    bottom-margin = 1.5\cm
    horizontal-shift =0\mm
    ragged-bottom = ##f
    ragged-last-bottom = ##f
    print-page-number = ##f
    annotate-spacing=##f
}

\layout {
    \context{
         \StaffGroup
         \override StaffGrouper #'staff-staff-spacing =      #'((basic-distance . 0) (minimum-distance . 0) (padding . 0) (stretchability . 0))
         \override StaffGrouper #'staffgroup-staff-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 0) (stretchability . 0))
    }
    \context{
         \Staff
         \override VerticalAxisGroup #'staff-staff-spacing =             #'((basic-distance . 0) (minimum-distance . 10) (padding . 0) (stretchability . 0))
         \override VerticalAxisGroup #'nonstaff-relatedstaff-spacing =   #'((basic-distance . 0) (minimum-distance . 0) (padding . 0) (stretchability . 0))
         \override VerticalAxisGroup #'nonstaff-unrelatedstaff-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 0) (stretchability . 0))
    }
    \context{
         \Lyrics
         \override LyricText #'font-size = #'0.0
         %\override LyricText #'font-size = #'1.0
         %\override LyricText #'font-name = "Tele-Antiqua" 
         \override LyricHyphen #'minimum-distance = #0.6
         \override LyricHyphen #'padding = #0.1
         \override LyricHyphen #'dash-period = #12
         \override VerticalAxisGroup #'nonstaff-relatedstaff-spacing =   #'((basic-distance . 0) (minimum-distance . 0)   (padding . 0.8) (stretchability . 10))
         \override VerticalAxisGroup #'nonstaff-nonstaff-spacing =       #'((basic-distance . 0) (minimum-distance . 0)   (padding . 0.0) (stretchability . 0))
         \override VerticalAxisGroup #'nonstaff-unrelatedstaff-spacing = #'((basic-distance . 0) (minimum-distance . 0)   (padding . 1.5) (stretchability . 100))
    }
}

%
% The Score to be printed on A4
%

\book {
    \bookOutputSuffix "Partitur"
    \paper { page-count = #4 }
    \markup { \general-align #X #LEFT \bold { \column { \fontsize #+2 \fill-line { {"Hugo Wolf: Sechs geistliche Lieder"} { "Partitur" }} \fontsize #+0 
              { "nach Gedichten von Joseph von Eichendorff" } \fontsize #-3 { " " } \fontsize #+4 { "Nr. 3: Resignation" } \fontsize #+5 { " " }}}}
    \score  { 
        \new ChoirStaff <<
            \new Staff {\new Voice = sop {\globMus \tempo "Mäßig langsam" 4=63 \sopMusic}}\new Lyrics \with{}\lyricsto sop {\satWords}
            \new Staff {\new Voice = alt {\globMus \altMusic}}\new Lyrics \with{}\lyricsto alt {\satWords}
            \new Staff {\new Voice = ten {\globMus \tenMusic}}\new Lyrics \with{}\lyricsto ten {\satWords}
            \new Staff {\new Voice = bas {\globMus \basMusic}}\new Lyrics \with{}\lyricsto bas {\bWords} >>
        \layout{
            system-count = #12
            \context {
                \Voice 
                \consists "Ambitus_engraver"
            }
        }
    }
}

%
% Single Voices to be printed on A4
%

\book {
    \bookOutputSuffix "Auszug-Sopran"
    \markup { \general-align #X #LEFT \bold { \column { \fontsize #+2 \fill-line { {"Hugo Wolf: Sechs geistliche Lieder"} { "Sopran" }} \fontsize #+0 
            {"nach Gedichten von Joseph von Eichendorff"} \fontsize #-3 { " " } \fontsize #+4 { "Nr. 3: Resignation" } \fontsize #+5 { " " }}}}
    \score { \new Staff { \globMus \tempo "Mäßig langsam" 4=63 \sopMusic } \addlyrics \satWords  \layout { system-count = #10 }}
}


\book {
    \bookOutputSuffix "Auszug-Alt"
    \markup { \general-align #X #LEFT \bold { \column { \fontsize #+2 \fill-line { {"Hugo Wolf: Sechs geistliche Lieder"} { "Alt" }} \fontsize #+0 
            {"nach Gedichten von Joseph von Eichendorff"} \fontsize #-3 { " " } \fontsize #+4 { "Nr. 3: Resignation" } \fontsize #+5 { " " }}}}
    \score { \new Staff { \globMus \tempo "Mäßig langsam" 4=63 \altMusic } \addlyrics \satWords  \layout { system-count = #10 }}
}

\book {
    \bookOutputSuffix "Auszug-Tenor"
    \markup { \general-align #X #LEFT \bold { \column { \fontsize #+2 \fill-line { {"Hugo Wolf: Sechs geistliche Lieder"} { "Tenor" }} \fontsize #+0 
            {"nach Gedichten von Joseph von Eichendorff"} \fontsize #-3 { " " } \fontsize #+4 { "Nr. 3: Resignation" } \fontsize #+5 { " " }}}}
    \score { \new Staff { \globMus \tempo "Mäßig langsam" 4=63 \tenMusic } \addlyrics \satWords  \layout { system-count = #10 }}
}

\book {
    \bookOutputSuffix "Auszug-Bass"
    \markup { \general-align #X #LEFT \bold { \column { \fontsize #+2 \fill-line { {"Hugo Wolf: Sechs geistliche Lieder"} { "Baß" }} \fontsize #+0 
            {"nach Gedichten von Joseph von Eichendorff"} \fontsize #-3 { " " } \fontsize #+4 { "Nr. 3: Resignation" } \fontsize #+5 { " " }}}}
    \score { \new Staff { \globMus \tempo "Mäßig langsam" 4=63 \basMusic } \addlyrics \bWords  \layout { system-count = #10 }}
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% Video
%

#(set-global-staff-size 19)

#(set! paper-alist (cons '("video" . (cons (* 21 cm) (* 11.8125 cm))) paper-alist)) % We need a 16:9 paper format

\include "videohelper.ily"    % include only _once_. Exactly one score with \layout {...} must follow, at least one score with \midi {...} must follow.

%\noPageRepetitions           % If you use noPageRepetitions there will be a pdf with all objects that change color dependent on moment colored,
                              % but _without_ repeated pages. Use as long as you tune the score layout.
%\noColorStems                % Don't give color to stems and flags
%\noColorDots                 % Don't give color to dots
%\noColorHeads                % Don't color notehedas
                            
% The following three commands might be used to override defaults defined in the mkvideo script:
                              %
#(videoResolution 1280 720 )  % Defaults to 1280 x 720. Use default, 1920x1080, 1024x576 or other resolutions.
#(videoPreset "veryslow")     % Defaults to "veryslow". Possible values: "ultrafast", "superfast", "veryfast", "faster", "fast", "medium", "slow", "slower", "veryslow", "placebo"
                              %   There is no reason to use placebo. I recommend "ultrafast" during development and "veryslow" for release.
#(audioBitRate "128k")        % Defaults to 128k

\book {
    \bookOutputSuffix "Partitur-Video"
    \paper {
        #(set-paper-size "video")
        top-margin = 10\mm
        bottom-margin = 10\mm
        line-width = 190\mm
        left-margin = 12\mm
        page-top-space = 0\mm
        horizontal-shift = 0\mm
        ragged-bottom = ##f
        ragged-last-bottom = ##f
        print-page-number = ##f
        page-breaking = #ly:optimal-breaking
        system-count = 14
        max-systems-per-page = 1
        min-systems-per-page = 1
        top-system-spacing = #'((basic-distance . 0) (minimum-distance . 7) (padding . 0) (stretchability . 0))
        last-bottom-spacing = #'((basic-distance . 0) (minimum-distance . 8) (padding . 0) (stretchability . 0))
    }

    % The title page. There must be exactly _one_ title page .
    
    \markup {
        \column {
            \vspace #0
            %\fill-line { \fontsize #18.0 \override #'(font-name . "Black Jack" ) "Resignation" }
            \fill-line { \fontsize #18.0 "Resignation" }
            \vspace #2
            \fill-line { \fontsize #5.0 "Composer: Hugo Wolf (1860-1903)" }
            \vspace #.4
            \fill-line { \fontsize #5.0 "Poet: Joseph von Eichendorff (1788-1857) )" }
            \vspace #1.5
            \fill-line { \fontsize #5.0 "Engraved by Knut Petersen using Lilypond 2.19.56" }
            %\vspace #0
            %\fill-line{\center-column{  \epsfile #X #25 #"LilypondLogo.eps" }}
        }
    }

    \pageBreak % Start score on page 2
    
    \score  { 
        \new ChoirStaff <<
            \new Staff {\new Voice = sop {\globMus \tempo "Mäßig langsam" 4=63 \sopMusic}}\new Lyrics \with{}\lyricsto sop {\satWords}
            \new Staff {\new Voice = alt {\globMus \altMusic}}\new Lyrics \with{}\lyricsto alt {\satWords}
            \new Staff {\new Voice = ten {\globMus \tenMusic}}\new Lyrics \with{}\lyricsto ten {\satWords}
            \new Staff {\new Voice = bas {\globMus \basMusic}}\new Lyrics \with{}\lyricsto bas {\bWords} >>
        
        \layout{
            \context {
                \Voice 
                \consists "Ambitus_engraver"
           }
           \context{
                \Staff
                \override VerticalAxisGroup #'staff-staff-spacing =             #'((basic-distance . 0) (minimum-distance . 0) (padding . 3.0) (stretchability . 100))
           }
            \context{
                \Lyrics
                \override VerticalAxisGroup #'nonstaff-relatedstaff-spacing =   #'((basic-distance . 0) (minimum-distance . 0) (padding . 1.0) (stretchability . 100))
                \override VerticalAxisGroup #'nonstaff-unrelatedstaff-spacing = #'((basic-distance . 0) (minimum-distance . 0) (padding . 1.5) (stretchability . 100))
            }
        }
    }
} \pdfforvideo % This passes the name of the pdf to be used for video production to mkvideo

%
% Some definitions used for midi generation ... you probably want to change instrument names
% and you might change or delete the volume overrides ...
%
#(define my-absolute-volume-alist '())
#(set! my-absolute-volume-alist (append '(("ff" . 1.00) '("f" . 0.90) ("mf" . 0.81) ("mp" . 0.73) ("p" . 0.66) ("pp" . 0.59)) my-absolute-volume-alist))
#(define-public (my-dynamic-absolute-volume s) (assoc-get s my-absolute-volume-alist))
  
panmidi = { 
    \set Score.dynamicAbsoluteVolumeFunction = #my-dynamic-absolute-volume
    \set Staff.midiInstrument = #"pan flute" 
    \set Staff.midiMinimumVolume = #0.00
    \set Staff.midiMaximumVolume = #1.0
    \set Staff.midiReverbLevel   = #1.0
}

pianomidi = {
    \set Score.dynamicAbsoluteVolumeFunction = #my-dynamic-absolute-volume
    \set Staff.midiInstrument = #"acoustic grand" 
    \set Staff.midiMinimumVolume = #0.00
    \set Staff.midiMaximumVolume = #0.65
    \set Staff.midiReverbLevel   = #1.0
}

% Video 1: All voices played with a pan flute
%
%          r1*5 \tempo 4 = 60 after \sopMusic adds some silence to the end of the midi file.
%          Without an event like \tempo silence at the end would be deleted, so we need it.

\book{
    \bookOutputSuffix "Video-Alle"
    \score {
        <<
            \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #-1.00   { \tempo 4=63 \sopMusic  r1*5 \tempo 4 = 60}}
            \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #-0.33   { \altMusic }}
            \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+0.33   { \tenMusic }}
            \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+1.00   { \basMusic }}
        >>
        \midi {}
    }
} \midiforvideo % this passes the name of midi files to be used for video production to mkvideo

%
% Video 2 to 5 all use a low volume piano version of all voices in the background ...
%
pianoback = {
    <<
        \new Staff { \globMus \pianomidi \set Staff.midiPanPosition = #-1.00   { \tempo 4=63 \sopMusic  r1*5 \tempo 4 = 60}}
        \new Staff { \globMus \pianomidi \set Staff.midiPanPosition = #-0.33   { \altMusic }}
        \new Staff { \globMus \pianomidi \set Staff.midiPanPosition = #+0.33   { \tenMusic }}
        \new Staff { \globMus \pianomidi \set Staff.midiPanPosition = #+1.00   { \basMusic }}
    >>
}

%
% ... and a higher volume pan flute for the emphasized voice
%
\book{ \bookOutputSuffix "Video-Alle-Grand" \score { \pianoback \midi {} }} \midiforvideo
\book{ \bookOutputSuffix "Video-Sopran" \score { << \pianoback \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+0.00 { \sopMusic }} >> \midi {} }} \midiforvideo
\book{ \bookOutputSuffix "Video-Alt"    \score { << \pianoback \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+0.00 { \altMusic }} >> \midi {} }} \midiforvideo
\book{ \bookOutputSuffix "Video-Tenor"  \score { << \pianoback \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+0.00 { \tenMusic }} >> \midi {} }} \midiforvideo
\book{ \bookOutputSuffix "Video-Bass"   \score { << \pianoback \new Staff { \globMus \panmidi \set Staff.midiPanPosition = #+0.00 { \basMusic }} >> \midi {} }} \midiforvideo
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to