Am 13.09.2016 um 02:29 schrieb Paul:
Hi Knut,

Sounds cool!  I'd like to check it out when I get a chance.  I'm curious how it 
compares with ly2video?

https://github.com/aspiers/ly2video

Some differences between my script and ly2video.py:
=================================
-> ly2video supports older versions of lilypond, my script needs at least 
version 2.19.23
->  ly2video requires clean 7-bit source files, it's almost unusable for vocal 
music if the lyrics text
      requires characters from european languages that use diacritics (german, 
french, ...) or completely
      different characters (russian ....). My script does not have this 
limitation.
-> ly2video is very slow compared to my script (see below), especially on a 
multi-core cpu
-> ly2video files are big, even if you turn off the cursor
-> ly2video uses a single very long system and cuts part from that. This is a 
problem if the
     number of instruments used is not constant.
-> my script does not generate a cursor as I believe that it is useless --- if 
you know how to read
     music, you do not need it, if you don't know how to read music it does not 
help either.
-> There are some bugs in ly2video that cause it to loose sync sometimes (but 
there are probably
     bugs in my script / videohelper.ily too)

Some measurements
=============

Test: Converting a lilypond source of J.S. Bach Invention Nr. 1
System: OS: Linux, cpu: i4790K cpu

ly2video, set to generate no cursor and identical Y-resolution
======================================
Processing time: 63.0 +/- 0.5 seconds
size of video file: 10.498.048 bytes

My script with h264 preset "ultrafast"
=======================
Processing time: 6.45 +/- 0.15 seconds (includes lilypond processing time of 
1.0 +/- 0.05s)
size of video file: 4.134.850 bytes

My script with h264 preset "veryslow"
=======================
Processing time 12.5 +/- 0.1 seconds (includes lilypond processing time of 1.0 
+/- 0.05s)
size of video file: 1.843.136 bytes

Attached find a new version of my script and an example source
========================================
Changes: -> Add metronome ticks at start of music
                -> remove temporary files
                -> limit number of parallel jobs to (virtual or real) cpu cores 
+ 1
                -> fix a bug in videohelper.ily
Missing :  -> errors are ignored most of the time ...

cu,
 Knut

#!/bin/bash

######################################################################
# Copyright (C) 2016 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.
######################################################################

# FPS=n: video files will use n frames per second
FPS=25
# TITLETIME: number of seconds the title page shall be visible
TITLETIME=6.0
# AFTERTIME
AFTERTIME=4.0
# PRESET: x264 preset to be used by ffmpeg for final output
PRESET=veryslow
PRESET=ultrafast
# DEBUG: n != 0 turns on debugging mode (verbose output)
DEBUG=0
# CLEAN: n != 0 enables deletion of all temporary files
CLEAN=1

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 checking dependencies ...
weneedprog ls sort tail uniq grep sed usleep bc gs pdftk lilypond fluidsynth 
sox ffmpeg
weneeddata /usr/share/sounds/sf2/FluidR3_GM.sf2 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
}

echo checking videohelper.notes ...
checknotes "LILYSOURCE" "LILYSOURCE undefined"
checknotes "VIDEOSOURCE" "VIDEOSOURCE undefined"
checknotes "MIDISOURCE" "MIDISOURCE undefined"
checknotes "tempo" "no tempo definition"
checknotes "note" "not a single note event"
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`
MIDILIST=`grep MIDISOURCE videohelper.notes | sed -e 
"s/MIDISOURCE=\([[:print:]]*\).midi/\1/" | sort | uniq | sed ':a;N;$!ba;s/\n/ 
/g'`

LASTMOMENT=$(echo `sort -n videohelper.notes | grep 'note\|rest' | tail -n 1 | \
            sed -e 
's/\([0-9.]*\)\([[:space:]]*\)\(note\|rest\)\([[:space:]]*\)\([0-9.]*\)/\1+\5/'`
 | bc -l)
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:]]//"`

ARVT[1]=$TITLETIME
for M in `seq 1 $PAGES`;
do
    ARVT[$((M+1))]=`bc <<<${ARTIMES[$((M+1))]}-${ARTIMES[$M]}`
done
ARVT[$MOMENTS]=`bc <<<${ARVT[$MOMENTS]}+$AFTERTIME`
ARVT[2]=`bc <<<${ARVT[2]}+$METROTIME`
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.47\" \score { \drums { wbl4 4 4 4 } \midi { \tempo 4 = 
$FIRSTTEMPO } }" > $TDIR/metronome.ly
cd $TDIR
lilypond metronome.ly &> /dev/null &
cd ..

echo generating tsilence.wav ...
sox -n -r 44100 -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 -ln --fast-render=$TDIR/$M-tmp1.wav  
/usr/share/sounds/sf2/FluidR3_GM.sf2 $M.midi &> $TDIR/$M-tmp1.wav.log &
done

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


echo synchronizing ...
wait
fluidsynth -ln --fast-render=$TDIR/metronome.wav  
/usr/share/sounds/sf2/FluidR3_GM.sf2 $TDIR/metronome.midi &> 
$TDIR/metronome.wav.log &

echo "generating 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=pnggray -sOutputFile=- 
$TDIR/page$((P)).pdf | \
    ffmpeg -y -framerate 1/100000 -i - \
        -vf scale=1024:512 -c:v libx264 -tune stillimage -preset ultrafast \
        -pix_fmt yuv420p -r 25 -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
     grep -o "page [[:digit:]]*" videohelper.notes | sort -n -k 2 | sed -e 
"s/\(page\) \([[:digit:]]*\)/file \1\2.h264/" > $TDIR/concat.txt
     ffmpeg -y -f concat -i $TDIR/concat.txt -i $TDIR/$M.wav -c:v libx264 -tune 
stillimage \
            -preset $PRESET -pix_fmt yuv420p -r 25 -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 
-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
%%%% Copyright (C) 2016 Knut Petersen <knut_peter...@t-online.de>
%%%%
%%%% This file contains code derived from Lilypond's ly/event-listener.ly.
%%%% There the following copyright notice was included:
%%%%
%%%% Copyright (C) 2011--2015 Graham Percival <gra...@percival-music.ca>
%%%%
%%%% Other parts of this file are based on code provide by
%%%% Thomas Morley <thomasmorle...@gmail.com>, see
%%%% 
http://lilypond.1069038.n5.nabble.com/intercepting-implicit-explicit-page-breaks-td194196.html
%%%%
%%%% Needs at least lilypond version 2.19.23!
%%%%
%%%% 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.
%%%%
%%%% You should have received a copy of the GNU General Public License
%%%% along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
#(define out (open-output-file "videohelper.notes"))

% #(define lastmoment 0.000)

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

#(define (moment-grace->string moment)
   "Prints a moment without grace note(s) as a float such as
0.25000.  Grace notes are written with the grace duration as a
separate \"dashed\" number, i.e. 0.25000-0.12500.  This allows any
program using the output of this function to interpret grace notes
however they want (half duration, quarter duration?  before beat,
after beat?  etc.)."
   (if
       (zero? (ly:moment-grace-numerator moment))
       (ly:format "~a" (format-moment moment))
       ;; grace notes have a negative numerator, so no "-" necessary
       (ly:format
         "~a~a"
         (format-moment moment)
         (format-moment
                       (ly:make-moment
                        (ly:moment-grace-numerator moment)
                        (ly:moment-grace-denominator moment))))))

#(define (make-output-string-line context values)
   "Constructs a tab-separated string beginning with the
score time (derived from the context) and then adding all the
values.  The string ends with a newline."
   (let* ((moment (ly:context-current-moment context)))
    (string-append
     (string-join
       (append
         (list (moment-grace->string moment))
         (map
             (lambda (x) (ly:format "~a" x))
             values))
       "\t")
     "\n")))


#(define (print-line context . values)
   "Prints the list of values (plus the score time) to a file, and
optionally outputs to the console as well.  context may be specified
as an engraver for convenience."
   (if (ly:translator? context)
       (set! context (ly:translator-context context)))
    (display (make-output-string-line context values) out)
    )

#(define (format-tempo engraver event)
   (if (ly:event-property  event 'metronome-count) 
       (print-line engraver "tempo"
         ( / 60
             (* (ly:event-property  event 'metronome-count)
                (format-moment (ly:duration-length (ly:event-property event 
'tempo-unit))))))))
   
         

#(define (format-time engraver event)
   (print-line engraver "time"))

#(define (format-rest engraver event)
   (print-line engraver
               "rest"
               (format-moment (ly:duration-length
                               (ly:event-property event 'duration)))
               ))

#(define (format-note engraver event)
     (print-line engraver
                 "note"
                 (format-moment (ly:duration-length
                                 (ly:event-property event 'duration)))
                ))

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

\paper {
        #(define (page-post-process layout pages) 
(print-pages-first-bar-numbers layout pages #t))
}

#(define* (print-pages-first-bar-numbers layout pages #:optional print-to-file)
  (let* ((lines (map (lambda (page) (ly:prob-property page 'lines)) pages))
         ;; list of systems of each pages
         (sys
           (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))
         (sys-moment-location
           (map
             (lambda (m)
               (if (and (not (null? m)) (ly:grob? (car m)))
                   (grob::when (car m))
                   #f))
             sys))
         (formatted-output
           (map
             (lambda (page m)
               (if m
                   (format #f "~a page ~a\n" (format-moment m) page)
                   (format #f "page ~a contains no music\n" page))
                   )
             (iota (length pages) 1 1)
            sys-moment-location))
         )
    (if (not (null? sys-moment-location))
        (begin
           (for-each (lambda (i) (display i out)) formatted-output))
            (for-each display formatted-output)))

  ; (format out "lastmoment is ~a\n"  lastmoment)

  ) 

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

pdfforvideo = #(define-void-function () () (format out "~a~a~a" "VIDEOSOURCE=" 
current-outfile-name ".pdf\n"))

midiforvideo = #(define-void-function () () (format out "~a~a~a" "MIDISOURCE=" 
current-outfile-name ".midi\n"))
\version "2.19.47"
\include "articulate.ly"

% This file demonstrates how to generate sheet music and video from a single
% lilypond source file. Put it into a directory together with videohelper.ily
% and the mkvideo script, then translate it with
%
%    lilypond JSBI1
%    ./mkvideo
%
% mkvideo features:
%
%   1. mkvideo is fast as it runs processes in parallel if possible
%
%   2. mkvideo keeps music and audio synchronized even if there are
%      tempo changes in the music and if the number of systems per
%      page is not constant
%
% Some INSANE tempo changes to test sync algorithm
%

voiceone = \relative c' {
  \time 4/4
  \set Score.tempoHideNote = ##f
  \tempo "Schnell"  4=80 
  r16 c[d e] f[d e c] g'8[c b^\prall c] d16[g, a b] c[a b g] d'8[g f^\prall g]
  e16[a g f] e[g f a] g[f e d] c[e d f] e[d c b] a[c b d] c[b a g] fis[a g b]
  \tempo 4=60 % only for testing
  a8[d,] c'8.[^\mordent d16] b[a g fis] e[g fis a] g[b a c] b[d c e]
  d[b32 c d16 g] b,8[^\prall a16 g] g8 r r4 r16 g[a b] c[a b g] fis8^\prall r
  \tempo 4=40 % only for testing 
  r4 r16 a[b c] d[b c a] b8 r r4 r16 d[c b] a[c b d] c8 r r4 r16 e[d c]
  \tempo 4=60 % only for testing
  b[d cis e] d8[cis d e] f[a, b! cis] d[fis, gis a] b[c] d4 ~ d16[e, fis gis]
  \tempo 4=50 % only for testing
  a[fis gis e] e'[d c e] d[c b d] c[a' gis b] a[e f d] gis,[f' e d] c8[b16 a]
  a16[a' g f] e[g f a] g2 ~ g16[e f g] a[f g e] f2 ~ f16[g f e] d[f e g]
  \tempo 4=80 % only for testing
  f2 ~ f16[d e f] g[e f d] e2 ~ e16[c d e] f[d e c] d[e f g] a[f g e] f[g a b]
  c[a b g] c8[g] e[d16 c] c[bes a g] f[a g bes] a[b c e,]
  \set Score.tempoHideNote = ##t
  \tempo 4=65 d [ \tempo 4=50 c' \tempo 4=35 f, \tempo 4=20 b] \tempo 4=60
  <c g e>1^\fermata\arpeggio \bar "|."
}

voicetwo = \relative c {
  \clef "bass" r2 r16 c[d e] f[d e c] g'8[g,] r4 r16 g'[a b] c[a b g] c8[b c d]
  e[g, a b] c[e, fis g] a[b] c4 ~ c16[d, e fis] g[e fis d] g8[b, c d] e[fis g e]
  b8.[c16] d8[d,] r16 g[a b] c[a b g] d'8[g fis g] a16[d, e fis] g[e fis d]
  a'8[d c d] g,16[\clef "treble" g' f e] d[f e g] f8[e f d] e16[a g f] e[g f a]
  g8[f g e] f16[bes a g] f[a g bes] a[g f e] d[f e g] f[e d c] b[d c e] d[c b a]
  gis[b a c] \clef "bass" b8[e,] d'8.[^\mordent e16] c[b a g!] fis[a gis b]
  a[c b d] c[e d f] e8[a, e' e,] a8[a,] r4 r16 e''16[d c] b[d cis e]
  d2 ~ d16[a b c] d[b c a] b2 ~ b16[d c b] a[c b d] c2 ~ c16[g a bes] c[a bes g]
  a8[bes a g] f[d' c bes] a[f' e d] e16[d, e f] g[e f d] e8[c d e] f16[d e f]
  g8[g,] <c c,>1 _\fermata \arpeggio \bar "|."
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% PRINT version A4
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

# ( set-global-staff-size 17.0 )

\book{
    \header {
        composer = "Johann Sebastian Bach (1685-1750)"
        title = "Invention 1"
        opus = "BWV 772"
        tagline     = ##f
    }  
    \paper {
        #(set-paper-size "a4")
        left-margin = 1.5\cm
        line-width = 18\cm
        top-margin = 1.5\cm
        bottom-margin = 1.5\cm
        horizontal-shift = 0\mm
        ragged-bottom = ##f
        ragged-last-bottom = ##f
        print-page-number = ##f
    } 
    \score {
        \new PianoStaff <<
            \set PianoStaff.connectArpeggios = ##t
            \context Staff = "one" << \voiceone >>
            \context Staff = "two" << \voicetwo >>
        >>
        
        \layout{
            indent = 0.0
        }
    }
}

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% VIDEO version
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

#(set! paper-alist (cons '("video" . (cons (* 21 cm) (* 10.5 cm))) paper-alist))

\include "videohelper.ily"

# ( set-global-staff-size 24 )

\book{
   \header {
        title = \markup  \center-column {
          \line \bold \fontsize #5 { Invention 1 } \vspace #.25
          \line \bold \fontsize #2 { Johann Sebastian Bach } \vspace #.5
          \line \medium \fontsize #0 { Video made with the help of Lilypond}
          \line \medium \fontsize #0 { and other open source tools.} \vspace #.5
          \line \medium \fontsize #0 { Demonstrates how to synchronize video and audio even in }
          \line \medium \fontsize #0 { the presence of tempo changes and in case of a variable}
          \line \medium \fontsize #0 { number of systems per page.}
        }
        tagline = ##f
    }
    \paper {
        #(set-paper-size "video")
        left-margin = 1\cm
        line-width = 19.5\cm
        top-margin = 1\cm
        bottom-margin = 1\cm
        horizontal-shift = 0\mm
        ragged-bottom = ##f
        ragged-last-bottom = ##f
        print-page-number = ##f
        max-systems-per-page = #2
    }

    \pageBreak
    
    \score {
        \new PianoStaff <<
            \set PianoStaff.connectArpeggios = ##t
            \context Staff = "one" << \voiceone >>
            \context Staff = "two" << \voicetwo >>    
        >>
        \layout{
            indent = 0.0
        }
    }
} \pdfforvideo

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%
%% MIDI
%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

panmidi = { \set Staff.midiInstrument = #"pan flute" 
    \set Staff.midiMinimumVolume = #0.2
    \set Staff.midiMaximumVolume = #0.2
}

pianomidi = { \set Staff.midiInstrument = #"acoustic grand" 
    \set Staff.midiMinimumVolume = #0.2
    \set Staff.midiMaximumVolume = #0.2
}


\book{
    \score { 
        \unfoldRepeats \articulate <<
            \new PianoStaff <<
                \set PianoStaff.connectArpeggios = ##t
                \context Staff = "one" << {\panmidi \voiceone {r1*3 \tempo 1 = 1}} >>
                \context Staff = "two" << {\panmidi \voicetwo} >>    
            >>
        >>
        \midi {   
            \context {
                \Score
                midiMinimumVolume = #0.0
                midiMaximumVolume = #1.0
            }
        }
    }
} \midiforvideo

\book{
    \score { 
        \unfoldRepeats \articulate <<
            \new PianoStaff <<
                \set PianoStaff.connectArpeggios = ##t
                \context Staff = "one" << {\pianomidi \voiceone {r1*3 \tempo 1 = 1}} >>
                \context Staff = "two" << {\pianomidi \voicetwo} >>    
            >>
        >>
        \midi {   
            \context {
                \Score
                midiMinimumVolume = #0.0
                midiMaximumVolume = #1.0
            }
        }
    }
} \midiforvideo
_______________________________________________
lilypond-user mailing list
lilypond-user@gnu.org
https://lists.gnu.org/mailman/listinfo/lilypond-user

Reply via email to