+2003-05-25 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ * lily/key-performer.cc (create_audio_elements): always use major
+ key
+
+ * Documentation/user/internals.itely: updates
+
+ * input/regression/beam-break.ly: new file.
+
+ * lily/beam.cc (brew_molecule): handle broken beams (i.e. print
+ beams if starting or terminating stems have 'beaming set.)
+
+ * lily/beam-engraver.cc (process_music): add forbidBeamBreak
+ property.
+
+ * lily/parser.yy (verbose_command_req): add comment about scales.
+
2003-05-25 Heikki Junes <hjunes@cc.hut.fi>
* lilypond-indent.el: adjust regexps in bracket-matching.
chapter documents the tools included in the distribution to do so.
There are other tools that produce LilyPond input, for example GUI
sequencers and XML converters. Refer to the
-@uref{website,http://lilypond.org} for more details.
+@uref{http://lilypond.org,website} for more details.
@refbugs
-musedata2ly converts only a small subset musedata.
+@file{musedata2ly} converts only a small subset of musedata.
@node Invoking mup2ly
@section Invoking mup2ly
@refbugs
-Currently, only plain notes (pitches, durations), voices and staves are
+Currently, only plain notes (pitches, durations), voices, and staves are
converted.
@chapter Advanced topics
-When LilyPond is run, it reads an input file. During parsing, Music
-objects are created. This music is interpreted, which is done by
-contexts, that produce graphical objects. This section discusses
-details of these three concepts, and how they are glued together with
-the embedded Scheme interpreter.
+When LilyPond is run, it reads an input file which is parsed. During
+parsing, Music objects are created. This music is interpreted, which
+is done by contexts, that produce graphical objects. This section
+discusses details of these three concepts, and how they are glued
+together with the embedded Scheme interpreter.
@menu
* Interpretation context::
@menu
* Creating contexts::
* Default contexts::
-* Context evaluation::
* Context properties::
+* Context evaluation::
+* Defining contexts::
* Engravers and performers::
-* Changing context definitions::
* Defining new contexts::
@end menu
Interpretation contexts are objects that only exist during program
run. During the interpretation phase (when @code{interpreting music}
-is interpreted to standard output), the music expression in a
+is printed on the standard output), the music expression in a
@code{\score} block is interpreted in time order, the same order in
-which hear and play the music. During this phase, the interpretation
-context holds the state for the current point within the music, for example
+which we hear and play the music. During this phase, the interpretation
+context holds the state for the current point within the music, for
+example
@itemize @bullet
@item What notes are playing at this point?
@end lilypond
@noindent
-In this example, the @code{c} and @code{d} are printed on the
-default staff. For the @code{e}, a context Staff called
-@code{another} is specified; since that does not exist, a new
-context is created. Within @code{another}, a (default) Voice context
-is created for the @code{e4}. When all music referring to a
-context is finished, the context is ended as well. So after the
-third quarter, @code{another} is removed.
+In this example, the @code{c} and @code{d} are printed on the default
+staff. For the @code{e}, a context @code{Staff} called @code{another}
+is specified; since that does not exist, a new context is created.
+Within @code{another}, a (default) Voice context is created for the
+@code{e4}. A context is ended when when all music referring it has
+finished, so after the third quarter, @code{another} is removed.
@node Default contexts
@subsection Default contexts
-Most music expressions do not need an explicit @code{\context}
-declaration: they inherit the notation context from their parent. In
+Every top level music is interpreted by the @code{Score} context; in
+other words, you may think of @code{\score} working like
+
+@example
+\score @{
+ \context Score @var{music}
+@}
+@end example
+
+Music expressions inherit their context from the enclosing music
+expression. Hence, it is not necessary to explicitly specify
+@code{\context} for most expressions. In
the following example, only the sequential expression has an explicit
context. The notes contained therein inherit the @code{goUp} context
from the enclosing music expression.
\notes \context Voice = goUp { c'4 d' e' }
@end lilypond
-There are some quirks that you must keep in mind when dealing with
-defaults:
-
-First, every top level music is interpreted by the Score context; in other
-words, you may think of @code{\score} working like
-
-@example
-\score @{
- \context Score @var{music}
-@}
-@end example
Second, contexts are created automatically to be able to interpret the
music expressions. Consider the following example.
@end lilypond
@noindent
-The sequential music is interpreted by the Score context initially
-(notice that the @code{\context} specification is redundant), but when a
-note is encountered, contexts are setup to accept that note. In this
-case, a Thread, Voice, and Staff context are created. The rest of the
-sequential music is also interpreted with the same Thread, Voice, and
-Staff context, putting the notes on the same staff, in the same voice.
-
-@node Context evaluation
-@subsection Context evaluation
-
-Scheme code can be used to modify contexts. The syntax for this is
-
-@example
- \applycontext @var{function}
-@end example
-
-@var{function} should be a Scheme function taking a single argument,
-being the context to apply it with. The following code will print the
-current bar number on the standard output during the compile.
-
-@example
- \applycontext
- #(lambda (x)
- (format #t "\nWe were called in barnumber ~a.\n"
- (ly:get-context-property x 'currentBarNumber)))
-@end example
-
+The sequential music is interpreted by the Score context initially,
+but when a note is encountered, contexts are setup to accept that
+note. In this case, a Thread, Voice, and Staff context are created.
+The rest of the sequential music is also interpreted with the same
+Thread, Voice, and Staff context, putting the notes on the same staff,
+in the same voice.
@node Context properties
@subsection Context properties
-
-Notation contexts have properties. These properties are from
-the @file{.ly} file using the following expression:
+Contexts have properties. These properties are set from the @file{.ly}
+file using the following expression:
@cindex @code{\property}
@cindex context properties
@cindex properties, context
the inverse of @code{\property \set}.
-@node Engravers and performers
-@subsection Engravers and performers
+@node Context evaluation
+@subsection Context evaluation
+
+Contexts can be modified during interpretation with Scheme code. The
+syntax for this is
+@example
+ \applycontext @var{function}
+@end example
+
+@var{function} should be a Scheme function taking a single argument,
+being the context to apply it to. The following code will print the
+current bar number on the standard output during the compile.
+
+@example
+ \applycontext
+ #(lambda (x)
+ (format #t "\nWe were called in barnumber ~a.\n"
+ (ly:get-context-property x 'currentBarNumber)))
+@end example
+
+
+
+@node Defining contexts
+@subsection Defining contexts
-@node Changing context definitions
-@subsection Changing context definitions
@cindex context definition
@cindex translator definition
-The most common way to define a context is by extending an existing
-context. You can change an existing context from the paper block by
-first initializing a translator with an existing context identifier:
+The most common way to create a new context definition is by extending
+an existing one. An existing context from the paper block is copied
+by referencing a context identifier:
@example
\paper @{
Every predefined context has a standard identifier. For example, the
@code{Staff} context can be referred to as @code{\StaffContext}.
-@noindent
The context can then be modified by setting or changing properties,
e.g.
@example
\translator @{
\StaffContext
- Stem \set #'thickness = #1.2
+ Stem \set #'thickness = #2.0
defaultBarType = #"||"
@}
@end example
variable, and apply to one @code{\translator} definition by
referencing that variable.
-@node Defining new contexts
-@subsection Defining new contexts
+@node Engravers and performers
+@subsection Engravers and performers
-@cindex engraver
-@cindex plug-in
Each context is composed of a number of building blocks, or plug-ins
called engravers. An engraver is a specialized C++ class that is
objects, and the @code{Skip_event_swallow_translator} only swallows
(silently gobbles) @code{SkipEvent}s.
+
+
+@cindex engraver
+@cindex plug-in
+
An existing context definition can be changed by adding or removing an
engraver. The syntax for these operations is
@example
A list of all engravers is in the internal documentation,
see @internalsref{All engravers}.
+@node Defining new contexts
+@subsection Defining new contexts
+
+
It is also possible to define new contexts from scratch. To do this,
you must define give the new context a name. In the following
example, a very simple Staff context is created: one that will put
@cindex evaluating Scheme
@cindex LISP
-LilyPond internally uses GUILE, a Scheme-interpreter.
-
-
-Scheme is used to represent data throughout the whole program.
-
-In some places of the input file, Scheme expressions also form valid
-syntax: wherever it is allowed, GUILE can be accessed directly by
-entering a hash-sign (@code{#}). The expression following the
-hash-sign is evaluated as Scheme. For example, the boolean value @var{true} is
-@code{#t} in Scheme, so for LilyPond @var{true} looks like @code{##t},
-and can be used in property assignments:
-@example
- \property Staff.autoBeaming = ##f
-@end example
+LilyPond internally uses GUILE, a Scheme-interpreter, to represent
+data throughout the whole program, and glue together different program
+modules. For advanced usage, it is sometimes necessary to access and
+program the Scheme interpreter.
-Scheme is a full-blown programming language, from the LISP family. and
-a full discussion is outside the scope of this document. Interested
-readers are referred to the website @uref{http://www.schemers.org/}
-for more information on Scheme.
+Scheme is a full-blown programming language, from the LISP
+family. and a full discussion is outside the scope of this document.
+Interested readers are referred to the website
+@uref{http://www.schemers.org/} for more information on Scheme.
The GUILE library for extension is documented at
@uref{http://www.gnu.org/software/guile}.
@end ifinfo
@menu
+* Inline Scheme::
* Input variables and Scheme::
* Scheme datatypes::
* Assignments::
@end menu
+@node Inline Scheme
+@subsection Inline Scheme
+
+Scheme expressions can be entered in the input file by entering a
+hash-sign (@code{#}). The expression following the hash-sign is
+evaluated as Scheme. For example, the boolean value @var{true} is
+@code{#t} in Scheme, so for LilyPond @var{true} looks like @code{##t},
+and can be used in property assignments:
+@example
+ \property Staff.autoBeaming = ##f
+@end example
+
+
@node Input variables and Scheme
@subsection Input variables and Scheme
There is also a form of scoping: in the following example, the
@code{\paper} block also contains a @code{traLaLa} variable, which is
-independent of the outer \traLaLa.
+independent of the outer @code{\traLaLa}.
@example
traLaLa = \notes @{ c'4 d'4 @}
\paper @{ traLaLa = 1.0 @}
toplevel scope.
Both variables and scoping are implemented in the GUILE module system.
-A anonymous Scheme module is attached to each scope. An assignment of
+An anonymous Scheme module is attached to each scope. An assignment of
the form
@example
traLaLa = \notes @{ c'4 d'4 @}
@noindent
is internally converted to a Scheme definition
@example
- (define traLaLa @var{Scheme value of @code{\notes ... }})
+ (define traLaLa @var{Scheme value of ``@code{\notes ... }''})
@end example
This means that input variables and Scheme variables may be freely
The following list are all lilypond specific types, that
can exist during parsing:
-@itemize @bullet
+@table @code
@item Duration
@item Identifier
@item Input
@item Pitch
@item Score
@item Translator_def
-@end itemize
+@end table
During a run, transient objects are also created and destroyed.
-@itemize @bullet
+@table @code
@item Grob: short for `Graphical object'.
@item Scheme_hash_table
@item Music_iterator
not yet user-accessible.
@item Font_metric: An object representing a font.
-@end itemize
+@end table
Many functions are defined to manipulate these data structures. They
are all listed and documented in the internals manual, see
@subsection Assignments
@cindex Assignments
-Identifiers allow objects to be assigned to names during the parse
-stage. To assign an identifier, use @var{name}@code{=}@var{value}.
-To refer to an identifier, precede its name with a backslash:
+Variables allow objects to be assigned to names during the parse
+stage. To assign a variable, use
+@example
+@var{name}@code{=}@var{value}
+@end example
+To refer to a variable, precede its name with a backslash:
`@code{\}@var{name}'. @var{value} is any valid Scheme value or any of
-the input-types listed above. Identifier assignments can appear at top
+the input-types listed above. Variable assignments can appear at top
level in the LilyPond file, but also in @code{\paper} blocks.
-An identifier can be created with any string for its name, but you will
-only be able to refer to identifiers whose names begin with a letter,
-being entirely alphabetical. It is impossible to refer to an identifier
-whose name is the same as the name of a keyword.
-
-The right hand side of an identifier assignment is parsed completely
-before the assignment is done, so it is allowed to redefine an
-identifier in terms of its old value, e.g.
+A variable can be created with any string for its name, but for
+accessing it in the LilyPond syntax, its name must consist of
+alphabetic characters only, and may not be a keyword of the syntax.
+There are no restrictions for naming and accessing variables in the
+Scheme interpreter,
+The right hand side of a variable assignment is parsed completely
+before the assignment is done, so variables may be redefined in terms
+of its old value, e.g.
+@c
@example
foo = \foo * 2.0
@end example
-When an identifier is referenced, the information it points to is
-copied. For this reason, an identifier reference must always be the
-first item in a block.
+When a variable is referenced in LilyPond syntax, the information it
+points to is copied. For this reason, an variable reference must
+always be the first item in a block.
@example
\paper @{
@node Music storage format
@section Music storage format
+Music in LilyPond is entered as music expressions. This section
+discusses different types of music expressions, and explains
+information is stored internally. This internal storage is accessible
+through the Scheme interpreter, so music expressions may be
+manipulated using Scheme functions.
+
@menu
* Music expressions::
* Internal music representation::
@subsection Music expressions
@cindex music expressions
-Music in LilyPond is entered as a music expression. Notes, rests, lyric
-syllables are music expressions, and you can combine music expressions
-to form new ones, for example by enclosing a list of expressions in
-@code{\sequential @{ @}} or @code{< >}. In the following example, a
-compound expression is formed out of the quarter note @code{c} and a
-quarter note @code{d}:
+Notes, rests, lyric syllables are music expressions. Small music
+expressions may be combined to form larger ones, for example by
+enclosing a list of expressions in @code{\sequential @{ @}} or @code{<
+>}. In the following example, a compound expression is formed out of
+the quarter note @code{c} and a quarter note @code{d}:
@example
\sequential @{ c4 d4 @}
-@node Manipulating music expressions
-@subsection Manipulating music expressions
-
When a music expression is parsed, it is converted into a set of
Scheme music objects. The defining property of a music object is that
it takes up time. Time is a rational number that measures the length
All classes of music are listed in the internals manual, under
@internalsref{Music classes}.
@item
-Each music object is represented by a C++ object. may be represented
-by different C++ classes. For technical reasons, different music
-objects may be represented by different C++ object types. For example,
-a note is @code{Event} object, while @code{\grace} creates a
-@code{Grace_music} object.
-
- The distinctions between different C++ types will disappear in the
-future.
+Each music object is represented by a C++ object. For technical
+reasons, different music objects may be represented by different C++
+object types. For example, a note is @code{Event} object, while
+@code{\grace} creates a @code{Grace_music} object.
+
+We expect that distinctions between different C++ types will disappear
+in the future.
@end itemize
The actual information of a music expression is stored in properties.
@code{element}. The body of a repeat is in @code{element} property of
@internalsref{RepeatedMusic}, and the alternatives in @code{elements}.
-These properties and objects can be directly accessed and manipulated,
-through the @code{\apply} mechanism. Scheme functions can read and
-write properties using the functions @code{ly:get-music-property} and
-@code{ly:set-music-property!}.
+@node Manipulating music expressions
+@subsection Manipulating music expressions
+Music objects and their properties can be accessed and manipulated
+directly, through the @code{\apply} mechanism. Scheme functions can
+read and write properties using the functions
+@code{ly:get-music-property} and @code{ly:set-music-property!}.
+6
The syntax for @code{\apply}
@example
\apply #@var{func} @var{music}
LilyPond's default output format is @TeX{}. Using the option @option{-f}
(or @option{--format}) other output formats can be selected also, but
-currently none of them reliably work.
+currently none of them work reliably.
At the beginning of the output file, various global parameters are defined.
It also contains a large @code{\special} call to define PostScript routines
@menu
* Reporting bugs::
* Website::
+* Point and click::
* Invoking ly2dvi:: Titling LilyPond scores.
@end menu
Set init file to @var{file} (default: @file{init.ly}).
@item -m,--no-paper
@cindex MIDI
-Disable @TeX{} output. If you have a @code{\midi} definition midi output
+Disable @TeX{} output. If you have a @code{\midi} definition MIDI output
will be generated.
@item -M,--dependencies
Output rules to be included in Makefile.
@uref{http://www.lilypond.org/}.
-@c . {Point and click}
-@menu
-* Point and click::
-@end menu
@node Point and click
-@subsection Point and click
+@section Point and click
@cindex poind and click
Point and click lets you find notes in the input by clicking on them in
@item KDVI. A dvi viewer for KDE. You need KDVI from KDE 3.0 or
newer. Enable option @emph{Inverse search} in the menu @emph{Settings}.
+Apparently, KDVI does not process PostScript specials correctly. Beams
+and slurs will not be visible in KDVI.
+
@cindex Xdvi
@cindex KDVI
@cindex KDE
property in the score.
@end table
-@subsection Environment variables
-
-@table @code
-
-
-@end table
-
@menu
-* Integrating Texinfo and music::
-* Integrating La@TeX{} and music::
-* Integrating HTML and music::
-* Music fragment options::
-* Invoking lilypond-book::
+* Integrating Texinfo and music::
+* Integrating La@TeX{} and music::
+* Integrating HTML and music::
+* Music fragment options::
+* Invoking lilypond-book::
@end menu
-TODO: explain how to use lilypond fonts in text.
@cindex texinfo
@chapter Notation manual
@html
-<!--- @@WEB-TITLE@@=Reference Manual --->
+<!--- @@WEB-TITLE@@=Notation manual --->
@end html
@subsection Chords
A chord is formed by a enclosing a set of pitches in @code{<<} and
-@code{>>}.
+@code{>>}. A chord may be followed by a duration, and a set of
+articulations, just like simple notes.
+
+Additionally, fingerings and articulations may be attached to
+individual pitches of the chord:
+
+@lilypond[singleline,verbatim,relative 1]
+ <<f-1 a-^ c-5>>
+@end lilypond
+
-TODO: accidental overides?
@node Rests
@subsection Rests
-@node Automatic note splitting
-@subsection Automatic note splitting
-@c FIXME: This subsection does not belong in @ref{Note entry}.
-
-Long notes can be converted automatically to tied notes. This is done
-by replacing the @internalsref{Note_heads_engraver} by the
-@internalsref{Completion_heads_engraver}.
-
-@example
- \paper @{ \translator @{
- \ThreadContext
- \remove "Note_heads_engraver"
- \consists "Completion_heads_engraver"
- @} @}
-@end example
-
-For example,
-@example
- \time 2/4
- c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2
-@end example
-
-@lilypond[noindent]
-\score{
- \notes\relative c'{
- \time 2/4
- c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2
- }
- \paper { \translator {
- \ThreadContext
- \remove "Note_heads_engraver"
- \consists "Completion_heads_engraver"
- } }
- }
-@end lilypond
-
-This engraver splits all running notes at the bar line, and inserts
-ties. One of its uses is to debug complex scores: if the measures are
-not entirely filled, then the ties exactly show how much each measure
-is off.
-
-@refbugs
-
-Not all durations (especially those containing tuplets) can be
-represented exactly; the engraver will not insert tuplets.
-
@node Tuplets
@subsection Tuplets
@node Easier music entry
@section Easier music entry
@cindex Music entry
+
+When entering music it is easy to introduce errors. This section deals
+with tricks and features of the input language that help when entering
+music, and find and correct mistakes.
+
+Some features of the input language ease entering music, for example
+the use of variables (for splitting up large pieces of music), and
+unfolded repeats for writing repetitive parts. They are described in
+other sections (see @ref{Repeats} and @ref{Assignments}), since they
+are not especially aimed at easing entry
+
+It is also possible to use external programs, for example GUI
+interfaces, or MIDI transcription programs, to enter or edit
+music. Refer to the website for more information. Finally, there are
+tools make debugging easier, by linking the input file and the output
+shown on screen. See @ref{Point and click} for more information.
+
+
@menu
* Relative octaves::
* Bar check::
* Skipping corrected music::
@end menu
-When entering music it is easy to introduce errors. This section deals
-with tricks and features that help entering music, and find and
-correct mistakes. It is also possible to use external programs, for
-example GUI interfaces, or MIDI transcription programs, to enter or
-edit music. Refer to the website for more information.
c d b bes a g c2 }
@end lilypond
+@node Automatic note splitting
+@subsection Automatic note splitting
+
+Long notes can be converted automatically to tied notes. This is done
+by replacing the @internalsref{Note_heads_engraver} by the
+@internalsref{Completion_heads_engraver}.
+
+@example
+ \paper @{ \translator @{
+ \ThreadContext
+ \remove "Note_heads_engraver"
+ \consists "Completion_heads_engraver"
+ @} @}
+@end example
+
+For example,
+@example
+ \time 2/4
+ c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2
+@end example
+
+@lilypond[noindent]
+\score{
+ \notes\relative c'{
+ \time 2/4
+ c2. c8 d4 e f g a b c8 c2 b4 a g16 f4 e d c8. c2
+ }
+ \paper { \translator {
+ \ThreadContext
+ \remove "Note_heads_engraver"
+ \consists "Completion_heads_engraver"
+ } }
+ }
+@end lilypond
+
+This engraver splits all running notes at the bar line, and inserts
+ties. One of its uses is to debug complex scores: if the measures are
+not entirely filled, then the ties exactly show how much each measure
+is off.
+
+@refbugs
+
+Not all durations (especially those containing tuplets) can be
+represented exactly; the engraver will not insert tuplets.
+
@c TODO: \paper block is identical in all of the below examples.
@c Therefore, it should somehow be included rather than duplicated all
-@c the time.
+@c the time. --jr
+
+@c why not make identifiers in ly/engraver-init.ly? --hwn
@item
@code{1. Punctum}
* A lead sheet::
* Listening to output::
* More movements :: Joining separate pieces of music
+* Single staff polyphony ::
+* Piano music::
* Organising larger pieces::
-* A piano excerpt:: Piano music
* Fine tuning a piece::
* An orchestral score:: Conductor's score and individual parts
* Integrating text and music:: Integrating text and music
A complete list of modifiers, and other options for layout are in the
reference manual section @ref{Chords}.
-
-TODO: template example with chord names, lyrics and staff.
+@cindex lead sheet
+When put together, chord names, lyrics and a melody form
+a lead sheet, for example:
+@lilypond[singleline,verbatim]
+\score {
+ <
+ \context ChordNames \chords { r8 c2:sus4 f }
+ \addlyrics
+ \notes \relative c' {
+ \partial 8
+ c8
+ \times 2/3 { f g g } \times 2/3 { g4-( a2-) } }
+ \context Lyrics \lyrics { I want to break free __ }
+ >
+ \paper{ }
+}
+@end lilypond
@node Listening to output
@section Listening to output
-
-@example
- \midi @{ \tempo 4=72@}
-
-@end example
MIDI (Musical Instrument Digital Interface) is a standard for
connecting and recording digital instruments. A MIDI file is like a
tape recording of a MIDI instrument. The @code{\midi} block makes the
accidentals that were mistyped, stand out very much when listening to
the musical transcription.
-@code{\midi} is similar to @code{\paper @{ @}}, since it also
-specifies an output method. You can specify the tempo using the
-@code{\tempo} command, in this case the tempo of quarter notes is set
-to 72 beats per minute.
-
+@code{\midi} can be used in similarly to @code{\paper @{ @}}, for
+example
+@example
+\score @{
+ @var{..music..}
+ \midi @{ \tempo 4=72@}
+ \paper @{ @}
+@}
+@end example
+Here, the tempo is specified using the @code{\tempo} command. In this
+case the tempo of quarter notes is set to 72 beats per minute.
@node More movements
will be at the left.
+@node Single staff polyphony
+@section Single staff polyphony
-@node Organising larger pieces
-@section Organising larger pieces
+When different melodic lines are combined on a single staff, these are
+printed as polyphonic voices: each voice has its own stems, slurs
+and beams, and the top voice has the stems up, while the bottom voice
+has stems down.
-TODO: discuss identifiers, p&c, .
+Entering such parts is done by entering each voice as a sequence (with
+@code{@{ .. @}}), and combing those simultaneously, separating the
+voices with @code{\\}:
-@separate
-@example
-\version "1.5.72"
-@end example
-Lilypond and its language are still under development, and
-occasionally details of the syntax are changed. The @code{version}
-fragment indicates which LilyPond version the input file was written
-for. When you compile this file, the version number will be checked
-and you will get a warning when the file is too old. This version
-number is also used by the @code{convert-ly} program (See
-@ref{Invoking convert-ly}), which can used to update the file to the
-latest lily version.
+@lilypond[verbatim,relative]
+ < { a4 g2 f4-~ f4 } \\
+ { r4 g4 f2 f4 } >
+@end lilypond
+
+More features of polyphonic typesetting are in the notation manual,
+@ref{Polyphony}.
+@node Piano staffs
+@section Piano staffs
-@node A piano excerpt
-@section A piano excerpt
+@cindex staff switch, manual
+@cindex cross staff voice, manual
+@cindex @code{\translator}
-Our eighth subject is a piece of piano music. The fragment in the
-input file is a piano reduction of the G major Sinfonia by Giovanni
-Battista Sammartini, composed around 1740. It's in the source
-package under the name @inputfileref{input/tutorial,sammartini.ly}.
-@lilypondfile[smallverbatim]{sammartini.ly}
-As you can see, this example features multiple voices on one staff. To
-make room for those voices, their notes should be stemmed in opposite
-directions.
+@node Organising larger pieces
+@section Organising larger pieces
+TODO: discuss identifiers, p&c, .
@separate
@example
-viola = \notes \relative c' \context Voice = viola @{
+\version "1.5.72"
@end example
-In this example you see multiple parts on a staff. Each part is
-associated with one notation context. This notation context handles
-stems and dynamics (among other things). The type name of this
-context is @code{Voice}. For each part we have to make sure that
-there is precisely one @code{Voice} context, so we give it a unique
-name (`@code{viola}').
-
-@separate
-
-@cindex arpeggio
-
-
-
-
+Lilypond and its language are still under development, and
+occasionally details of the syntax are changed. The @code{version}
+fragment indicates which LilyPond version the input file was written
+for. When you compile this file, the version number will be
+checked. When the file is too old, a warning is issued. The version
+number is also used by the @code{convert-ly} program (See
+@ref{Invoking convert-ly}), which updates the file to the latest
+version automatically.
-@separate
-@example
- g'8. b,16
-@end example
-Relative octaves work a little differently with chords. The starting
-point for the note following a chord is the first note of the chord. So
-the @code{g} gets an octave up quote: it is a fifth above the starting
-note of the previous chord (the central C).
@separate
@example
@code{s} is a spacer rest. It does not print anything, but it does have
the duration of a rest. It is useful for filling up voices that
temporarily do not play. In this case, the viola does not come until one
-and a half measure later.
-
-@separate
-@example
-oboes = \notes \relative c'' \context Voice = oboe @{
-@end example
-Now comes a part for two oboes. They play homophonically, so we
-print the notes as one voice that makes chords. Again, we insure that
-these notes are indeed processed by precisely one context with
-@code{\context}.
-@separate
-@example
- s4 g8. b,16 c8 r <<e' g>>8. <<f a>>16
-@end example
-
-The oboes should have stems up to keep them from interfering with
-the staff-jumping bass figure. To do that, we use @code{\voiceOne}.
+and a half measure later.
@separate
@example
The piece of music to be `tripletted' is sequential music containing
three chords.
-@separate
-@example
-<
-@end example
-At this point, the homophonic music splits into two rhythmically
-different parts. We cannot use a sequence of chords to enter this, so
-we make a "chord of sequences" to do it. We start with the upper
-voice, which continues with upward stems:
-@separate
-@example
- @{ \times 2/3 @{ a8 g c @} c2 @}
-@end example
-
-@separate
-@example
-\\
-@end example
-Entering multiple voices is demonstrated here. Separate the
-components of the voice (single notes or entire sequences) with
-@code{\\} in a simultaneous music expression. The @code{\\} separators
-split first voice, second voice, third voice, and so on.
-
-As far as relative mode is concerned, the previous note is the
-@code{c'''2} of the upper voice, so we have to go an octave down for
-the @code{f}.
-@separate
-@example
-
- f,8 e e2
-@} >
-@end example
-This ends the two-part section.
-@separate
-@example
-\grace <<c, e>>8-( <<b d>>8.-\trill <<c e>>16 |
-@end example
-@cindex trill
-@cindex stemBoth
The bass has a little hoom-pah melody to demonstrate parts switching
between staves. Since it is repetitive, we use repeats:
written out in full eight times.
@separate
-@cindex staff switch, manual
-@cindex cross staff voice, manual
-@cindex @code{\translator}
-
-@example
-\translator Staff = down
-\stemUp
-c8
-\translator Staff = up
-\stemDown
-c'8 @}
-@end example
-Voices can switch between staves. Here you see two staff switching
-commands. The first one moves to the lower staff, the second one to
-the lower one. If you set the stem directions explicitly
-(using the identifiers @code{\stemUp} and @code{\stemDown}, the notes
-can be beamed together (despite jumping between staffs).
-
-@separate
-@example
-bassvoices = \notes \relative c' @{
-c4 g8. b,16
-\autochange Staff \hoomPah \context Voice
-@end example
-
-@separate
-@example
- \translator Staff = down
-@end example
-@cindex staff switch
-@cindex cross staff voice
-We want the remaining part of this melody on the lower staff, so we do a
-manual staff switch here.
-
-
-
-
-@separate
-@example
-\context PianoStaff
-@end example
- A special context is needed to get cross staff beaming right. This
-context is called @code{PianoStaff}.
-@separate
-@example
-\context Staff = bottom < \time 2/2 \clef bass
-@end example
-The bottom staff must have a different clef.
-@separate
-@example
-indent = 0.0
-@end example
-To make some more room on the line, the first (in this case the only)
-line is not indented. The line still looks very cramped, but that is due
-to the page layout of this document.
-
-
-@ignore
-[TODO:
-
-* font-size
-
-* Simple part combining in a Hymn
-@end ignore
-
-
@node Fine tuning a piece
@section Fine tuning a piece
The @code{printfilename} option adds the file name to the output.
-[TODO: include excercises? ]
--- /dev/null
+\header {
+ texidoc = "Beams can be printed across line breaks if forced.
+"
+
+}
+\version "1.7.19"
+
+\score { \notes \relative c'' {
+ \property Score.forbidBeamBreak = ##f
+ c2. c8-[ c8 \break c8 c8-] } }
beam_ = 0;
}
- if (beam_)
+ if (beam_ && to_boolean (get_property ("forbidBeamBreak")))
{
top_engraver ()->forbid_breaks ();
}
+
if (evs_drul_[START])
{
if (beam_)
/* creats*/ "Beam",
/* accepts */ "beam-event abort-event new-beam-event",
/* acks */ "stem-interface rest-interface",
-/* reads */ "beamMelismaBusy beatLength subdivideBeams",
+/* reads */ "beamMelismaBusy beatLength forbidBeamBreak subdivideBeams",
/* write */ "");
Molecule the_beam;
Real lt = me->get_paper ()->get_var ("linethickness");
- for (int i = 0; i< stems.size(); i++)
+ for (int i = 0; i<= stems.size(); i++)
{
- Grob * st =stems[i];
+ Grob * st = (i < stems.size()) ? stems[i] : 0;
- SCM this_beaming = st->get_grob_property ("beaming");
- Real xposn = st->relative_coordinate (xcommon, X_AXIS);
- Real stem_width = gh_scm2double (st->get_grob_property ("thickness")) *lt;
+ SCM this_beaming = st ? st->get_grob_property ("beaming") : SCM_EOL;
+ Real xposn = st ? st->relative_coordinate (xcommon, X_AXIS) : 0.0;
+ Real stem_width = st ? gh_scm2double (st->get_grob_property ("thickness")) *lt : 0 ;
/*
We do the space left of ST, with lfliebertjes pointing to the
right from the left stem, and rfliebertjes pointing left from
right stem.
*/
- if (i > 0)
- {
- SCM left = gh_cdr (last_beaming);
- SCM right = gh_car (this_beaming);
+ SCM left = (i>0) ? gh_cdr (last_beaming) : SCM_EOL;
+ SCM right = st ? gh_car (this_beaming) : SCM_EOL;
- Array<int> fullbeams;
- Array<int> lfliebertjes;
- Array<int> rfliebertjes;
+ Array<int> fullbeams;
+ Array<int> lfliebertjes;
+ Array<int> rfliebertjes;
- for (SCM s = left;
- gh_pair_p (s); s =gh_cdr (s))
+ for (SCM s = left;
+ gh_pair_p (s); s =gh_cdr (s))
+ {
+ int b = gh_scm2int (gh_car (s));
+ if (scm_memq (gh_car(s), right) != SCM_BOOL_F)
{
- int b = gh_scm2int (gh_car (s));
- if (scm_memq (gh_car(s), right) != SCM_BOOL_F)
- {
- fullbeams.push (b);
- }
- else
- {
- lfliebertjes.push (b);
- }
+ fullbeams.push (b);
}
- for (SCM s = right;
- gh_pair_p (s); s =gh_cdr (s))
+ else
{
- int b = gh_scm2int (gh_car (s));
- if (scm_memq (gh_car(s), left) == SCM_BOOL_F)
- {
- rfliebertjes.push (b);
- }
+ lfliebertjes.push (b);
}
-
-
- Real w = xposn - last_xposn;
- Real stem_offset = 0.0;
- Real width_corr = 0.0;
- if (i == 1)
+ }
+ for (SCM s = right;
+ gh_pair_p (s); s =gh_cdr (s))
+ {
+ int b = gh_scm2int (gh_car (s));
+ if (scm_memq (gh_car(s), left) == SCM_BOOL_F)
{
- stem_offset -= last_width/2;
- width_corr += last_width/2;
+ rfliebertjes.push (b);
}
+ }
+
+ /*
+ how much to stick out for beams across linebreaks
+ */
+ Real break_overshoot = 3.0;
+ Real w = (i>0 && st)? xposn - last_xposn : break_overshoot;
+ Real stem_offset = 0.0;
+ Real width_corr = 0.0;
+ if (i == 1)
+ {
+ stem_offset -= last_width/2;
+ width_corr += last_width/2;
+ }
- if (i == stems.size() -1)
- {
- width_corr += stem_width/2;
- }
+ if (i == stems.size() -1)
+ {
+ width_corr += stem_width/2;
+ }
- if (gh_number_p (gap))
- {
- Real g = gh_scm2double (gap);
- stem_offset += g;
- width_corr -= 2*g;
- }
+ if (gh_number_p (gap))
+ {
+ Real g = gh_scm2double (gap);
+ stem_offset += g;
+ width_corr -= 2*g;
+ }
- Molecule whole = Lookup::beam (dydx, w + width_corr, thick);
- for (int j = fullbeams.size(); j--;)
- {
- Molecule b (whole);
- b.translate_axis (last_xposn - x0 + stem_offset, X_AXIS);
- b.translate_axis (dydx * (last_xposn - x0) + bdy * fullbeams[j], Y_AXIS);
- the_beam.add_molecule (b);
- }
+ Molecule whole = Lookup::beam (dydx, w + width_corr, thick);
+ for (int j = fullbeams.size(); j--;)
+ {
+ Molecule b (whole);
+ b.translate_axis (last_xposn - x0 + stem_offset, X_AXIS);
+ b.translate_axis (dydx * (last_xposn - x0) + bdy * fullbeams[j], Y_AXIS);
+ the_beam.add_molecule (b);
+ }
- if (lfliebertjes.size() || rfliebertjes.size())
- {
- Real nw_f;
+ if (lfliebertjes.size() || rfliebertjes.size())
+ {
+ Real nw_f;
+ if (st)
+ {
int t = Stem::duration_log (st);
SCM proc = me->get_grob_property ("flag-width-function");
SCM result = gh_call1 (proc, scm_int2num (t));
nw_f = gh_scm2double (result);
-
-
- /* Half beam should be one note-width,
- but let's make sure two half-beams never touch */
+ }
+ else
+ nw_f = break_overshoot;
- Real w = xposn - last_xposn;
- w = w/2 <? nw_f;
+ /* Half beam should be one note-width,
+ but let's make sure two half-beams never touch */
+ Real w = (i>0 && st) ? (xposn - last_xposn) : break_overshoot;
+ w = w/2 <? nw_f;
- Molecule half = Lookup::beam (dydx, w, thick);
- for (int j = lfliebertjes.size(); j--;)
- {
- Molecule b (half);
- b.translate_axis (last_xposn - x0, X_AXIS);
- b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS);
- the_beam.add_molecule (b);
- }
- for (int j = rfliebertjes.size(); j--;)
- {
- Molecule b (half);
- b.translate_axis (xposn - x0 - w , X_AXIS);
- b.translate_axis (dydx * (xposn-x0 -w) + bdy * rfliebertjes[j], Y_AXIS);
- the_beam.add_molecule (b);
- }
+ Molecule half = Lookup::beam (dydx, w, thick);
+ for (int j = lfliebertjes.size(); j--;)
+ {
+ Molecule b (half);
+ b.translate_axis (last_xposn - x0, X_AXIS);
+ b.translate_axis (dydx * (last_xposn-x0) + bdy * lfliebertjes[j], Y_AXIS);
+ the_beam.add_molecule (b);
+ }
+ for (int j = rfliebertjes.size(); j--;)
+ {
+ Molecule b (half);
+ b.translate_axis (xposn - x0 - w , X_AXIS);
+ b.translate_axis (dydx * (xposn-x0 -w) + bdy * rfliebertjes[j], Y_AXIS);
+ the_beam.add_molecule (b);
}
- }
+ }
+
last_xposn = xposn;
last_width = stem_width;
SCM pitchlist = key_req_->get_mus_property ("pitch-alist");
SCM proc = scm_primitive_eval (ly_symbol2scm ("accidentals-in-key"));
SCM acc = gh_call1 (proc, pitchlist);
- proc = scm_primitive_eval (ly_symbol2scm ("major-key"));
Pitch my_do (0,
gh_scm2int (ly_caar (pitchlist)),
to_c = my_do.transposed (Pitch(0,0,- my_do.get_alteration ()));
SCM c_pitchlist = transpose_key_alist (pitchlist, to_c.smobbed_copy());
- SCM major = gh_call1 (proc, c_pitchlist);
- audio_ = new Audio_key (gh_scm2int (acc), major == SCM_BOOL_T);
+ /*
+ MIDI keys are too limited for lilypond scales.
+
+ TODO: should probably detect minor key, though.
+ */
+ audio_ = new Audio_key (gh_scm2int (acc), true);
Audio_element_info info (audio_, key_req_);
announce_element (info);
key_req_ = 0;
#include <map> // UGH.
#include <assert.h>
+
#include "warn.hh"
#include "music-constructor.hh"
+
typedef Music* (*Music_ctor) ();
static std::map<String,Music_ctor> *ctors_map_;
tupletNumberFormatFunction = #denominator-tuplet-formatter
subdivideBeams = ##f
+ forbidBeamBreak = ##t
extraNatural = ##t
autoAccidentals = #'(Staff (same-octave . 0))
autoCautionaries = #'()
"Used to set the relative size of all grobs
in a context. This is done using the @code{Font_size_engraver}.")
+(translator-property-description 'forbidBeamBreak boolean?
+ "If false, allow line breaks during beams.")
+
(translator-property-description 'forceClef boolean? "Show clef symbol, even if it hasn't changed. Only active for the first clef after the property is set, not for the full staff.")
(translator-property-description 'graceAccidentalSpace number? "amount space to alot for an accidental")
(translator-property-description 'graceAlignPosition ly:dir? "put the grace note before or after the main note?")
(define-public (accidentals-in-key pitch-list)
"Count number of sharps minus number of flats"
(apply + (map cdr pitch-list)))
-
-(define-public (major-key pitch-list)
- "Characterise the key as major if the alteration of the
-third scale note is the same as that of the main note.
-Note: MIDI cannot handle other tonalities than major/minor.
-"
- ;; This charactersition is only true for a scale that starts at `c'.
- (if (not (equal? (car pitch-list) '(0 . 0)))
- (begin
- (ly:warn "Attempt to determine tonality of transposed scale")
- #t)
- (eq? (cdr (list-ref pitch-list 4)) (cdr (list-ref pitch-list 6))))
- )