]> git.donarmstrong.com Git - lilypond.git/commitdiff
* lily/lyric-phrasing-engraver.cc: remove
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 24 Feb 2004 22:14:32 +0000 (22:14 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Tue, 24 Feb 2004 22:14:32 +0000 (22:14 +0000)
* lily/lyric-engraver.cc: rewrite so lyric-phrasing-engraver no
longer necessary.

* lily/extender-engraver.cc (stop_translation_timestep): rewrite
so lyric-phrasing-engraver is no longer necessary.

* ly/engraver-init.ly: move Break_forbid_engraver to Voice, remove
Grob_pq_engraver from Staff.

* lily/grob-pq-engraver.cc: remove current_grobs array, read/write
busyGrobs directly.

34 files changed:
ChangeLog
Documentation/topdocs/NEWS.texi
Documentation/user/GNUmakefile
Documentation/user/introduction.itely
Documentation/user/refman.itely
input/regression/lyric-extender.ly
input/regression/lyric-phrasing-new.ly [deleted file]
input/regression/lyric-phrasing.ly
input/regression/quote-transposition.ly [new file with mode: 0644]
input/regression/quote.ly
input/regression/stanza-number.ly
lily/extender-engraver.cc
lily/forbid-break-engraver.cc
lily/grob-pq-engraver.cc
lily/hyphen-engraver.cc
lily/include/context.hh
lily/include/music.hh
lily/include/pitch.hh
lily/include/translator.hh
lily/lyric-combine-music-iterator.cc
lily/lyric-engraver.cc
lily/lyric-hyphen.cc
lily/lyric-phrasing-engraver.cc [deleted file]
lily/melisma-translator.cc
lily/music.cc
lily/my-lily-lexer.cc
lily/note-performer.cc
lily/parser.yy
lily/quote-iterator.cc
lily/recording-group-engraver.cc
ly/engraver-init.ly
scm/define-context-properties.scm
scm/part-combiner.scm
scripts/convert-ly.py

index c9a4c5eb843caac30d15ad2e843a252b5bbe0826..07ad3e19e261bd0d8c132496abae985622c0b8ae 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
 
 2004-02-24  Han-Wen Nienhuys   <hanwen@xs4all.nl>
 
+       * lily/lyric-phrasing-engraver.cc: remove
+       
+       * lily/lyric-engraver.cc: rewrite so lyric-phrasing-engraver no
+       longer necessary. 
+
+       * lily/extender-engraver.cc (stop_translation_timestep): rewrite
+       so lyric-phrasing-engraver is no longer necessary.
+
+       * ly/engraver-init.ly: move Break_forbid_engraver to Voice, remove
+       Grob_pq_engraver from Staff.
+
+       * lily/grob-pq-engraver.cc: remove current_grobs array, read/write
+       busyGrobs directly.
+
+       * input/regression/quote-transposition.ly: new file.
+
+       * lily/recording-group-engraver.cc (stop_translation_timestep):
+       store instrumentTuning too. 
+
+       * lily/quote-iterator.cc (process): transpose events using
+       instrumentTuning.
+
+       * scripts/convert-ly.py (FatalConversionError.subst): \set transposing
+       -> \tuning <pitch>
+
+       * lily/parser.yy (command_req): add \tuning command for setting
+       instrument tuning of staff.
+
+       * Documentation/user/GNUmakefile
+       ($(outdir)/lilypond/lilypond.html): ugh: use perl iso. sed.
+
        * Documentation/user/refman.itely (Customized accidental rules):
        typo.
 
index 32d53d7fbfeff91a20e24980a819ceebe9ba9469..a5fce91ffd34d8fb7d20ed54f1fc77f41705abff 100644 (file)
@@ -18,11 +18,16 @@ Version 2.1.13
 
 @itemize @bullet
 
+
 @item Cue notes can  now be quoted directly from the parts that
-contain them. For example,
+contain them. This will take into account tunings of source and target
+instrument. For example,
 
 @verbatim
-\addquote oboe \notes\relative c' { fis4 fis fis fis }
+\addquote clarinet \notes\relative c' {
+  \tuning bes
+  fis4 fis fis fis
+}
 
 \score {
     \notes \relative c'' {
@@ -31,7 +36,13 @@ contain them. For example,
 }
 @end verbatim
 
+@item The transposition of an instrument can be specified using the
+@code{\tuning} command. The following command specifies an E-flat alto
+saxophone:
 
+@example
+  \tuning es'
+@end example 
 
 @item The naming of exported Scheme functions now follows Scheme conventions.
 Changes be applied to Scheme files with convert-ly:
index a9a3c97fa28e4b51a322505f447f865d111b5fb2..038605846a2d55150ade901ced4328232e61930c 100644 (file)
@@ -68,7 +68,7 @@ $(outdir)/lilypond/lilypond.html: $(outdir)/lilypond.texi
        mkdir -p $(dir $@)
        $(MAKEINFO) -I$(outdir) --output=$(outdir)/lilypond --html $<
        $(MAKEINFO) -I$(outdir) --output=$@ --html --no-split --no-headers $<
-       sed -i 's!../lilypond-internals!lilypond-internals/!g' $(outdir)/lilypond.html
+       perl -i~ -pe 's!../lilypond-internals!lilypond-internals/!g' $(outdir)/lilypond.html
        rm -f $(outdir)/lilypond/*.png $(outdir)/lilypond/*.ly 
        -ln -f $(outdir)/*.png $(outdir)/*.ly $(outdir)/lilypond/
 
index a05bf1f00ca4f3480ac532c651c39939fb620fcd..d0618c72d9644a32061e6db42619c45611b571dc 100644 (file)
@@ -5,7 +5,7 @@
 @chapter Introduction
 
 There are a lot of programs that let you print sheet music with a
-computer, but most of them do not do good job.  Most computer
+computer, but most of them do not do good job.  Most computer
 printouts have a bland, mechanical look, and are unpleasant to play
 from.  If you agree with us on that, then you will like LilyPond: we
 have tried to capture the original look of hand-engraved music.  We
@@ -54,10 +54,10 @@ question is considered ``engraving'' (i.e. typography).
 For tackling the first problem, notation, we have broken up the
 problem into digestible (and programmable) chunks: every type of
 symbol is handled by a separate program module, a so-called plug-in.
-Each plug-in are completely modular and independent, so each can be
+Each plug-in is completely modular and independent, so each can be
 developed and improved separately.  When put together, the plug-ins
-can solve the music notation program in cooperation.  People that put
-graphics to musical ideas are called copyists or engravers, so by
+can solve the music notation problem in cooperation.  People that translate
+musical ideas to graphic symbols are called copyists or engravers, so by
 analogy, each plug-in is also called @code{engraver}.
 
 In the following example, we see how we start out with a note head
@@ -196,7 +196,7 @@ polyphony? In polyphonic notation, many voices can share a staff.
 
 In this situation, the accidentals and staff are shared, but the
 stems, slurs, beams, etc. are private to each voice. Hence, engravers
-should be grouped. The engravers for note head, stems, slurs, etc. go
+should be grouped. The engravers for note heads, stems, slurs, etc. go
 into a group called ``Voice context,'' while the engravers for key,
 accidental, bar, etc. go into a group called ``Staff context.'' In the
 case of polyphony, a single Staff context contains more than one Voice
@@ -223,7 +223,7 @@ printing.  Only a few decades ago, sheet music was made by cutting and
 stamping the music into zinc or pewter plates, in mirror image. The plate
 would be inked, and the depressions caused by the cutting and stamping
 would hold ink.  An image was formed by pressing paper to the
-plate. The stamping and cutting was completely done by hand. Making
+plate. The stamping and cutting was done completely by hand. Making
 corrections was cumbersome, so engraving had to be done correctly in
 one go. Of course, this was a highly specialized skill, much more so
 than the traditional process of printing books.
@@ -239,7 +239,7 @@ is acceptable for publication.
 
 
 Sheet music is performance material: everything is done to aid the
-musician in letting him perform better.  Music often is far away from
+musician in letting him perform better.  Music is often far away from
 its reader---it might be on a music stand. To make it clearly
 readable, traditionally printed sheet music always uses bold symbols,
 on heavy staff lines, and is printed on large sheets of paper.  This
@@ -338,7 +338,7 @@ combination should be put farther apart, and the notes of a down-up
 combination should be put closer together, all depending on the
 combined vertical positions of the notes. The first two measures are
 printed with this correction, the last two measures without. The notes
-in the last two measures form down-stem/up-stems clumps of notes.
+in the last two measures form down-stem/up-stem clumps of notes.
 
 @node Typography and program architecture
 @section Typography and program architecture
@@ -352,9 +352,9 @@ become a master.  As an engraver gets older and wiser, he will be able
 to produce better and more complex pieces.  A similar situation is
 present when putting typographical knowledge into a computer program.
 It is not possible to come up with a definitive solution for a problem
-at the first try. Instead, we start out with simple solution that
+on the first try. Instead, we start out with a simple solution that
 might cover 75% of the cases, and gradually refine that solution over
-the course of months or years, so 90 or 95 % of the cases are
+the course of months or years, so that 90 or 95 % of the cases are
 handled.
 
 This has an important implication for the design of the program: at
@@ -372,7 +372,7 @@ Until that time, users must have a way to deal with imperfections:
 these 25%, 10% or 5% of the cases that are not handled
 automatically. In these cases, a user must be able to override
 formatting decisions. To accomplish this we store decisions in generic
-variables, and let the user manipulate thosed.  For example, consider
+variables, and let the user manipulate those.  For example, consider
 the following fragment of notation:
 
 @lilypond
@@ -405,7 +405,7 @@ This was achieved with the following input statement:
    \once \override DynamicLineSpanner    #'padding = #4.0 
 @end example
 It increases the amount of space (@code{padding}) between the note and
-the dynamic symbol to 4.0 (which is measured in staff space, so 4.0
+the dynamic symbol to 4.0 (which is measured in staff spaces, so 4.0
 equals the height of a staff). The keyword @code{\once} indicates that
 this is a tweak: it is only done one time.
 
@@ -416,12 +416,13 @@ Scheme objects, and attached to graphical objects such as note heads
 and stems. The variables are a means to adjust formatting details in
 individual cases, but they are used in a more general manner.
 
-Consider the case of a publisher that is not satisfied with the in the
+Consider the case of a publisher that is not satisfied with the
 default layout, and wants heavier stems. Normally, they are @code{1.3}
 times the thickness of staff lines, but suppose that their editions
 require them to be twice the thickness of the staff lines. The same
 mechanism can be used to adjust a setting globally. By issuing the
-following command, the entire piece is now formatted with thicker stems:
+following command, the entire piece is now formatted with thicker
+stems:
 @example
     \override Score.Stem   #'thickness = #3.0 
 @end example
@@ -462,7 +463,7 @@ The full scope of this functionality certainly is intimidating, but
 there is no need to fear: normally, it is not necessary to define
 style-sheets or rewrite formatting functions. In fact, LilyPond gets a
 lot of formatting right automatically, so adjusting individual layout
-situations is not needed  often at all.
+situations is often not needed at all.
 
 
 @node Music representation
index 8224465a7d9451b65957273f6bf3274feb5227c0..f1c7160a5c5278bb91797dd9c2723f40cad1526f 100644 (file)
@@ -4065,12 +4065,12 @@ some common problems in orchestral music.
 * Bar numbers::                 
 * Instrument names::            
 * Transpose::                   
+* Instrument transpositions::   
 * Multi measure rests::         
 * Automatic part combining::    
 * Hiding staves::               
 * Different editions from one source::  
 * Quoting other voices::        
-* Sound output for transposing instruments::  
 @end menu
 
 @node Multiple staff contexts
@@ -4325,7 +4325,27 @@ you must put @code{\transpose} outside of @code{\relative}, since
 @code{\relative} will have no effect music that appears inside a
 @code{\transpose}.
 
+@node Instrument transpositions
+@subsection Instrument transpositions
 
+The key of a transposing instrument can also be specified.  This
+applies to many wind instruments, for example, clarinets (B-flat, A and
+E-flat), horn (F) and trumpet (B-flat, C, D and E-flat).
+
+@syntax
+
+The transposition is entered after the keyword @code{\transposition}:
+
+@example
+  \transposition bes   %%  B-flat clarinet
+@end example
+
+This command sets the property @code{instrumentTuning}. The value of
+this property is used for MIDI output and quotations.  It does not
+affect how notes are printed in the current staff.
+
+@cindex transposition, MIDI
+@cindex transposition, instrument
 
 
 @node Multi measure rests
@@ -4606,27 +4626,70 @@ Examples: @inputfileref{input/regression,tag-filter.ly}.
 @node Quoting other voices
 @subsection Quoting other voices
 
-TODO: document!
+With quotations, fragments of other parts can be inserted into a part
+directly. Before a part can be quoted, it must be marked especially as
+quotable. This is done with code @code{\addquote} command. The
+quotation may then be done with @code{\quote}
 
+@example
+  \addquote @var{name} @var{music}
+  \quote @var{name} @var{duration}  
+@end example
 
+@noindent
 
+Here, @var{name} is an identifying string. The @var{music} is any kind
+of music.  This is an example of @code{\addquote}:
 
+@verbatim
+\addquote clarinet \notes\relative c' {
+  f4 fis g gis
+}
+@end verbatim
 
-@node Sound output for transposing instruments
-@subsection Sound output for transposing instruments
+During a part, a piece of music can be quoted with the @code{\quote}
+command. 
+  
+@verbatim
+  \quote clarinet 2.
+@end verbatim
+
+This would cite 3 quarter notes (a dotted half note) of the previously
+added clarinet voice.
+
+Quotations take into account the transposition both source and target
+instruments, if they are specified using the @code{\transposition} command.
+
+@lilypond[verbatim fragment] 
+\addquote clarinet \notes\relative c' {
+  \transposition bes
+  f4 fis g gis
+}
+\score {
+  \notes {
+  e'8 f'8 \quote clarinet 2
+} }
+@end lilypond
+
+@refbugs
+
+Only the contents of the first @internalsref{Voice} occurring in an
+@code{\addquote} command will be considered for quotation, so
+@var{music} can not contain @code{\new} and @code{\context Voice}
+statements that would switch to a different Voice.
+
+
+@seealso
+
+In this manual: @ref{Instrument transpositions}.
+
+Examples: @inputfileref{input/regression,quote.ly}
+@inputfileref{input/regression,quote-transposition.ly}
+
+Internals: @internalsref{QuoteMusic}.
 
-When you want to make a MIDI file from a score containing transposed
-and untransposed instruments, you have to instruct LilyPond the pitch
-offset (in semitones) for the transposed instruments. This is done
-using the @code{transposing} property. It does not affect printed
-output:
 
-@cindex @code{transposing}
 
-@example
-        \set Staff.instrument = #"Cl. in B-flat"
-        \set Staff.transposing = #-2
-@end example
 
 
 @node Ancient notation
index 09b7758264febc8f9902cd8b456c84fad9224283..635b7a52aa3815f4527b8afd0fd2224a529c99db 100644 (file)
@@ -2,13 +2,13 @@
 
 \header { texidoc= "In lyric extenders, a syllable may be extended over several notes. "}
 
-    \paper { raggedright= ##t }
+\paper { raggedright= ##t }
 \score{
 \notes \relative c'    <<
-       \context Staff {
+       \context Voice = melody {
            c8[ ( d] )
            r4 f4 }
-       \context Lyrics \lyrics { xxx __ \skip 4 x  }
+       \lyricsto melody \context Lyrics \lyrics { ah __ ha  }
        >>
 }
 
diff --git a/input/regression/lyric-phrasing-new.ly b/input/regression/lyric-phrasing-new.ly
deleted file mode 100644 (file)
index 881e190..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-\version "2.1.26"
-\header {
-
-texidoc = "
-  Normally, the lyric is centered on the note head. However, on
-  melismata, the text is left aligned on the left-side of the note head.
-
-"
-}
-
-
-\score{
-<<     \notes \relative c' \context Voice = "bla" {
-           \autoBeamOff
-           c4( c16 d c b)  c4
-           d16[ e f g]
-           
-       }
-       \lyrics  \lyricsto  "bla" \context Lyrics {
-           al tijd
-           izzz
-       } >>
-       
-    \paper { raggedright = ##t }
-}
index 915791596a08581af5258ba24842fbe1a5c6b738..eef50b280e6afae2e9a348eeb5e28bd2223f90ec 100644 (file)
@@ -1,40 +1,25 @@
-
 \version "2.1.26"
-\header{
-  texidoc="
-  The multiple stanzas of lyric phrasing are aligned according to the start 
-  and end of a phrase.
-
-  By default, lyrics are centered with respect to the corresponding notes.
-
-@example
-           |        |        |     |      |
-          x|       x|       x|    x|     x|
+\header {
 
-     1:  Start  sentence  melisma      end.
-     2:  x         x         x______      x
-@end example
+texidoc = "
+  Normally, the lyric is centered on the note head. However, on
+  melismata, the text is left aligned on the left-side of the note head.
 
-  While there is a melisma, lyrics are followed by '__' and they
-  are left-aligned, in this case the third x."
+"
 }
 
-\paper { raggedright = ##t}
-\score {
-  \addlyrics
-    \context Voice = "v" \notes  \relative c'' {
-      \autoBeamOff
-      a a a8 ( a) a4
-    }
-  <<
-      \new Lyrics \lyricsto "v"  \lyrics {
-        \set stanza = "1:"
-        Start sentence melisma end.
-      }
-      \new Lyrics \lyricsto "v" \lyrics {
-        \set stanza = "2:"
-        x x x __ x.
-      }
-   >>
-}
 
+\score{
+<<     \notes \relative c' \context Voice = "bla" {
+           \autoBeamOff
+           c4( c16 d c b)  c4
+           d16[ e f g]
+           
+       }
+       \lyrics  \lyricsto  "bla" \context Lyrics {
+           alllll __ tijd
+           izzz
+       } >>
+       
+    \paper { raggedright = ##t }
+}
diff --git a/input/regression/quote-transposition.ly b/input/regression/quote-transposition.ly
new file mode 100644 (file)
index 0000000..66fdbab
--- /dev/null
@@ -0,0 +1,33 @@
+
+\header
+{
+
+    texidoc = "Quotations take into account the transposition of both  source and target.
+In this example, all instruments play sounding central C, the target is a instrument in F."
+
+}
+\version "2.1.26"
+
+
+\addquote clarinet \notes {
+    \transposition bes
+    d'16 d'16 d'8 
+    d'16 d'16 d'8 
+    d'16 d'16 d'8 
+    d'16 d'16 d'8 
+    }
+\addquote sax \notes {
+    \transposition es'
+    a8 a a a a a  a a 
+    }
+
+\score {
+    \notes{
+       \transposition f  % french horn
+       
+       g'4
+       << \quote clarinet 4 s4^"clar" >> 
+       << \quote sax 4 s4^"sax" >> 
+    }
+}
+
index a1f4daf1912c7718f84cc81581a1bf2572b5d891..567119a8473a1e413bfb4c56aa13b89c0ebdaecf 100644 (file)
@@ -7,11 +7,12 @@ music may be quoted. "
 }
 \version "2.1.26"
 
-\addquote bla \notes\relative c' { fis4 g a b }
+\addquote bla \notes\relative c' {
+    fis4 g a b }
 
 \score {
     \notes \relative c'' {
-       c8 d8 \quote 2 bla es8 gis  
+       c8 d8 \quote bla 2 es8 gis  
     }
 }
 
index 227402d2fbf8f7536d336b321733c416afad4439..7c38a47a60a1faf17dc6f86738301000d64680b3 100644 (file)
@@ -1,21 +1,25 @@
 \version "2.1.26"
 
 \header {
-texidoc = "Stanza numbers are put left of their lyric."
+texidoc = "Stanza numbers are put left of their lyric. Theyr are aligned in a column."
 }
 
 \score {
 <<
-    \notes { r4 r4 c4  c4 }
-    \context Lyrics
-    \lyrics {
+    \context Voice = "A" \notes \relative c'' { r4 r4 c4  c4 }
+    \lyricsto A \new Lyrics \lyrics  {
        \skip 2
        \set stanza = "1."
-       Foo8 Bar8
+       Foo8 
+    }
+    \lyricsto A \new Lyrics \lyrics {
+       \skip 2
+       \set stanza = "2."
+       FFFooooo8
     }
 >>
 
 \paper { raggedright = ##t } 
-} 
+}
 
 
index 2bf4c708702a437c1ca57497fd936b748e78ce1c..10f677105e05cd76361b4d644f284f123d10d8aa 100644 (file)
 #include "lyric-extender.hh"
 #include "item.hh"
 #include "engraver.hh"
+#include "context.hh"
+#include "group-interface.hh"
 
 class Extender_engraver : public Engraver
 {
   Music* ev_;
   Spanner* extender_;
-  Spanner * finished_extender_;  
+  Spanner * pending_extender_;  
 public:
   TRANSLATOR_DECLARATIONS(Extender_engraver);
 
@@ -37,34 +39,80 @@ private:
 Extender_engraver::Extender_engraver ()
 {
   extender_ = 0;
-  finished_extender_ = 0;
+  pending_extender_ = 0;
   ev_ = 0;
 }
 
+bool
+Extender_engraver::try_music (Music* r)
+{
+  if (ev_)
+    return false;
+
+  ev_ = r;
+  return true;
+}
+
+
+void
+Extender_engraver::process_music ()
+{
+  if (ev_)
+    {
+      extender_ = make_spanner ("LyricExtender");
+      announce_grob (extender_, ev_->self_scm());
+    }
+}
+
+
 void
 Extender_engraver::acknowledge_grob (Grob_info i)
 {
   Item * item =  dynamic_cast<Item*> (i.grob_);
-  // -> text_item
-  if (item && item->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
+
+  if (item
+      && item->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
     {
       if (extender_)
        extender_->set_bound (LEFT, item);
 
-      if (finished_extender_)
-       finished_extender_->set_bound (RIGHT, item);
+      if (pending_extender_)
+       pending_extender_->set_bound (RIGHT, item);
     }
 }
 
-
-bool
-Extender_engraver::try_music (Music* r)
+void
+Extender_engraver::stop_translation_timestep ()
 {
-  if (ev_)
-    return false;
+  if (pending_extender_ && pending_extender_->get_bound (RIGHT))
+    {
+      typeset_grob (pending_extender_);
+      pending_extender_ = 0;
+    }
 
-  ev_ = r;
-  return true;
+  if (extender_ || pending_extender_)
+    {
+      Context *voice = get_voice_to_lyrics (daddy_context_);
+      Grob* h =  (voice) ? get_current_note_head (voice) : 0;
+
+      if (h)
+       {
+         if (extender_)
+           Pointer_group_interface::add_grob (extender_,
+                                              ly_symbol2scm ("heads"), h);
+         if (pending_extender_)
+           Pointer_group_interface::add_grob (pending_extender_,
+                                              ly_symbol2scm ("heads"), h);
+       }           
+
+      if (extender_)
+       {
+         pending_extender_ = extender_;
+         extender_ = 0;
+       }
+    }
+
+  ev_ = 0;
 }
 
 void
@@ -97,50 +145,18 @@ Extender_engraver::finalize ()
       extender_ = 0;
     }
 
-  if (finished_extender_)
+  if (pending_extender_)
     {
-      completize_extender (finished_extender_);
-
-      if (!finished_extender_->get_bound (RIGHT))
-         finished_extender_->warning (_("unterminated extender"));
-      typeset_grob (finished_extender_);
-      finished_extender_ =0;
-    }
-}
+      completize_extender (pending_extender_);
 
-void
-Extender_engraver::process_music ()
-{
-  if (ev_)
-    {
-      extender_ = make_spanner ("LyricExtender");
-      announce_grob (extender_, ev_->self_scm());
+      if (!pending_extender_->get_bound (RIGHT))
+         pending_extender_->warning (_("unterminated extender"));
+      typeset_grob (pending_extender_);
+      pending_extender_ =0;
     }
 }
 
 
-void
-Extender_engraver::stop_translation_timestep ()
-{
-  if (finished_extender_ && finished_extender_->get_bound (RIGHT))
-    {
-      typeset_grob (finished_extender_);
-      finished_extender_ = 0;
-    }
-
-  if (finished_extender_ && extender_)
-    {
-      programming_error ("Haven't finished extender yet.");
-      typeset_grob (finished_extender_);
-      finished_extender_ =0;
-    }
-  
-  if (extender_)
-    finished_extender_ = extender_;
-  extender_ = 0;
-
-  ev_ = 0;
-}
 
 
 
index dbaad085684c3a4ed23d127ac6fc9195034c0eba..b2a5d802c5dae18b20415c297c540e10dd82b2bc 100644 (file)
@@ -12,14 +12,6 @@ public:
 
 Forbid_line_break_engraver::Forbid_line_break_engraver(){}
 
-ENTER_DESCRIPTION(Forbid_line_break_engraver,
-/* descr */       "Forbid line breaks when note heads are still playing at some point.",
-/* creats*/       "",
-/* accepts */     "",
-/* acks  */      "",
-/* reads */       "busyGrobs",
-/* write */       "");
-
 void
 Forbid_line_break_engraver::start_translation_timestep()
 {
@@ -43,3 +35,12 @@ Forbid_line_break_engraver::start_translation_timestep()
       busy = gh_cdr(busy);
     }
 }
+
+
+ENTER_DESCRIPTION(Forbid_line_break_engraver,
+/* descr */       "Forbid line breaks when note heads are still playing at some point.",
+/* creats*/       "",
+/* accepts */     "",
+/* acks  */      "",
+/* reads */       "busyGrobs",
+/* write */       "");
index 4fdf5d2b4f33febe41d3ac8699fc49b9835fe924..96d93ceec29deb8882fed58ce8764ec9ff6f5386 100644 (file)
 #include "grob.hh"
 #include "warn.hh"
 
-/*
-  TODO: should junk this engraver.
- */
-
-struct Grob_mom
-{
-  Grob * grob_ ;
-  Moment end_;
-  Grob_mom () {}
-  Grob_mom (Grob*gr, Moment e)
-  {
-    grob_ = gr;
-    end_ = e;
-  }
-};
-
-int compare  (Grob_mom const &a, Grob_mom const &b)
-{
-  return Moment::compare (a.end_, b.end_);
-}
-
-/****************/
-
 class Grob_pq_engraver: public Engraver
 {
 public:
   TRANSLATOR_DECLARATIONS(Grob_pq_engraver);
-
-  Array<Grob_mom> current_grobs_;
 protected:
   virtual void initialize ();
   virtual void acknowledge_grob (Grob_info);
@@ -52,13 +27,23 @@ Grob_pq_engraver::Grob_pq_engraver()
 {
 }
 
-
 void
 Grob_pq_engraver::initialize ()
 {
   daddy_context_->set_property ("busyGrobs", SCM_EOL); 
 }
 
+LY_DEFINE(ly_grob_pq_less_p, 
+         "ly:grob-pq-less?", 2 , 0 ,0, (SCM a, SCM b), 
+         "Compare 2 Grob PQ entries. Internal")
+{
+  if (Moment::compare (*unsmob_moment (gh_car (a)),
+                      *unsmob_moment (gh_car (b))) < 0)
+    return SCM_BOOL_T;
+  else
+    return SCM_BOOL_F;
+}
+         
 void
 Grob_pq_engraver::acknowledge_grob (Grob_info gi)
 {
@@ -79,45 +64,31 @@ Grob_pq_engraver::acknowledge_grob (Grob_info gi)
          l.main_part_ = 0;
        }
 
-      current_grobs_.push (Grob_mom (gi.grob_, n + l));
+      Moment end = n + l;
+      SCM lst = scm_acons (end.smobbed_copy (),
+                        gi.grob_->self_scm(),
+                        SCM_EOL);
+
+      SCM busy= get_property ("busyGrobs");
+      busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
+      daddy_context_->set_property ("busyGrobs", busy);
     }
 }
 
-LY_DEFINE(ly_grob_pq_less_p, 
-         "ly:grob-pq-less?", 2 , 0 ,0, (SCM a, SCM b), 
-         "Compare 2 Grob PQ entries. Internal")
-{
-  if ( Moment::compare (*unsmob_moment (gh_car (a)),
-                                     *unsmob_moment (gh_car (b))) < 0)
-    return SCM_BOOL_T;
-  else
-    return SCM_BOOL_F;
-}
-         
 
 void
 Grob_pq_engraver::stop_translation_timestep ()
 {
-  Moment now = now_mom();
-
-  current_grobs_.sort (&compare);
-  SCM current_list = SCM_EOL;
-  for (int i = current_grobs_.size(); i--;)
-    current_list = scm_cons (scm_cons (current_grobs_[i].end_.smobbed_copy(), 
-                                      current_grobs_[i].grob_->self_scm ()), current_list);
-
-  /*
-    We generate some garbage here.
-   */
-  SCM busy = get_property ("busyGrobs");
+  Moment now = now_mom ();
+  SCM start_busy = get_property ("busyGrobs");
+  SCM busy = start_busy;
   while (gh_pair_p (busy) && *unsmob_moment (gh_caar (busy)) == now)
     {
       busy = gh_cdr (busy);
     }
-  
-  busy = scm_merge_x (current_list, busy, ly_grob_pq_less_p_proc);
-  current_grobs_.clear ();
-  daddy_context_->set_property ("busyGrobs", busy);
+
+  if (start_busy != busy)
+    daddy_context_->set_property ("busyGrobs", busy);
 }
 
 void
@@ -133,7 +104,9 @@ Grob_pq_engraver::start_translation_timestep ()
        Todo: do something sensible. The grob-pq-engraver is not water
        tight, and stuff like tupletSpannerDuration confuses it.
        */
-      programming_error (_f("Skipped something?\nGrob %s ended before I expected it to end.", unsmob_grob (gh_cdar (busy))->name().to_str0()));
+      programming_error (_f("Skipped something?\nGrob %s ended before "
+                           "I expected it to end.",
+                           unsmob_grob (gh_cdar (busy))->name().to_str0()));
       
       busy = gh_cdr (busy);
     }
index dbf70c7414ebe4ad045edbefd7a42ef3c7e0144d..16b79b915face4a6c2b88464a2dc24b4800e132e 100644 (file)
@@ -92,7 +92,11 @@ Hyphen_engraver::finalize ()
       completize_hyphen (hyphen_);
 
       if (!hyphen_->get_bound (RIGHT))
-       hyphen_->warning (_ ("unterminated hyphen"));
+       {
+         hyphen_->warning (_ ("unterminated hyphen; removing"));
+         hyphen_->suicide ();
+       }
+
       typeset_grob (hyphen_);
       hyphen_ = 0;
     }
index aadc76bc67a79d3b45abfac72c82b5b2e28ba797..a47237fb03e5ab5a7ffe5aa3b60de0e90945e179 100644 (file)
@@ -76,8 +76,11 @@ void execute_pushpop_property (Context * trg, SCM prop, SCM eltprop, SCM val);
 SCM updated_grob_properties (Context* tg, SCM sym);
 Context * find_context_below (Context * where,
                    String type, String id);
+bool melisma_busy (Context*);
 
-Context * unsmob_context (SCM);
+Context *get_voice_to_lyrics (Context *lyrics);
+Grob *get_current_note_head (Context * voice);
+Context *unsmob_context (SCM);
 
 DECLARE_UNSMOB(Context,context);
 
index 8d96b195c6f465cba7ef2434792ead22bf1c9478..78d1be7bde982e4274190a3a77fc440e8397c372 100644 (file)
@@ -72,5 +72,6 @@ protected:
 DECLARE_UNSMOB(Music,music);
 
 Music* make_music_by_name (SCM sym);
+SCM ly_deep_mus_copy (SCM);
 
 #endif // MUSIC_HH
index d0891569c5353982acc7a428594c43bd581b6588..8a7f276aba7f454aaec6689e45b16e8afd88653f 100644 (file)
@@ -78,6 +78,7 @@ enum {
   DOUBLE_SHARP,
 };
 
+SCM ly_pitch_diff (SCM pitch, SCM  root);
 SCM ly_pitch_transpose (SCM p, SCM delta);
 DECLARE_UNSMOB(Pitch,pitch);
 
index de406a3db4c91ca58229bf76336a3e9fedd20427..57e3257a2ff94ea8268b04f38413df1f043906c8 100644 (file)
@@ -123,5 +123,4 @@ void add_translator (Translator*trans);
 
 Translator*get_translator (SCM s);
 DECLARE_UNSMOB(Translator,translator);
-bool melisma_busy (Translator*);
 #endif // TRANSLATOR_HH
index 1783677b8237411a1ce31a6c76846a022875ef92..4c176aacf2491b94e59c24fa8a611622c9d67f1f 100644 (file)
@@ -39,12 +39,10 @@ private:
 };
 
 
-#include "translator.hh"
-
 bool
-melisma_busy (Translator* tr)
+melisma_busy (Context* tr)
 {
-  SCM melisma_properties = tr->daddy_context_->get_property ("melismaBusyProperties");
+  SCM melisma_properties = tr->get_property ("melismaBusyProperties");
   bool busy = false;
 
   for (; gh_pair_p (melisma_properties);
index 6c7c2697dc7e036310e9ad6683a9d5b9967c41d8..20cf201bdcd04126e63b0d2f0a6c60d5ff85c589 100644 (file)
@@ -10,9 +10,9 @@
 #include "engraver.hh"
 #include "event.hh"
 #include "item.hh"
-#include "paper-def.hh"
+#include "context.hh"
 #include "font-metric.hh"
-#include "side-position-interface.hh"
+#include "note-head.hh"
 
 /**
    Generate texts for lyric syllables.  We only do one lyric at a time.  
@@ -28,17 +28,16 @@ protected:
 public:
   TRANSLATOR_DECLARATIONS(Lyric_engraver);
 private:
-  Music * req_;
+  Music * event_;
   Item* text_;
-};
-
-
 
+  Context* get_voice_context ();
+};
 
 Lyric_engraver::Lyric_engraver ()
 {
   text_ =0;
-  req_ =0;
+  event_ =0;
 }
 
 bool
@@ -46,9 +45,9 @@ Lyric_engraver::try_music (Music*r)
 {
   if (r->is_mus_type ("lyric-event"))
     {
-      if (req_)
+      if (event_)
        return false;
-      req_ =r;
+      event_ =r;
       return true;
     }
   return false;
@@ -57,24 +56,82 @@ Lyric_engraver::try_music (Music*r)
 void
 Lyric_engraver::process_music ()
 {
-  if (req_)
+  if (event_)
     {
       text_=  make_item ("LyricText");
       
-      text_->set_property ("text", req_->get_property ("text"));
-      announce_grob (text_, req_->self_scm());
+      text_->set_property ("text", event_->get_property ("text"));
+      announce_grob (text_, event_->self_scm());
     }
 }
 
+
+Context*
+get_voice_to_lyrics (Context *lyrics)
+{
+  SCM avc = lyrics->get_property ("associatedVoiceContext");
+  if  (Context *c = unsmob_context (avc))
+    return c;
+
+  SCM voice = lyrics->get_property ("associatedVoice");
+  String nm = lyrics->id_string_;
+
+  if (gh_string_p (voice))
+    nm = ly_scm2string (voice);
+  else
+    {
+      int idx = nm.index_last ('-');
+      if (idx >= 0)
+       nm = nm.left_string (idx);
+    }
+
+  Context *c =  lyrics->find_existing_context (ly_symbol2scm ("Voice"), nm);
+
+  if (c)
+    return c;
+
+  return lyrics->find_existing_context (ly_symbol2scm ("Voice"), "");
+}
+
+Grob *
+get_current_note_head (Context * voice)
+{
+  for (SCM s = voice->get_property ("busyGrobs");
+       gh_pair_p (s); s = gh_cdr (s))
+    {
+      Item*g = dynamic_cast<Item*> (unsmob_grob (gh_cdar (s)));
+         
+      if (g && !g->get_column ()
+         && Note_head::has_interface (g))
+       return g;
+    }
+         
+  return 0;  
+}
+
 void
 Lyric_engraver::stop_translation_timestep ()
 {
   if (text_)
     {
+      Context * voice = get_voice_to_lyrics (daddy_context_);
+
+      if (voice)
+       {
+         Grob *head = get_current_note_head (voice);
+
+         if (head)
+           {
+             text_->set_parent (head, X_AXIS);
+             if (melisma_busy (voice))
+               text_->set_property ("self-alignment-X", gh_int2scm (LEFT)); 
+           }
+       }
+      
       typeset_grob (text_);
       text_ =0;
     }
-  req_ =0;
+  event_ =0;
 }
 
 
index 93f20bca4ccb9e8983caf9a52028f0713a5765c0..f7a7221afdacd7aa935e2c18d64054c7e5a23444 100644 (file)
@@ -104,11 +104,15 @@ Hyphen_spanner::set_spacing_rods (SCM smob)
   do
     {
       r.item_l_drul_[d] = sp->get_bound (d);
-      r.distance_ += r.item_l_drul_[d]->extent (r.item_l_drul_[d], X_AXIS)[-d];
+      if (r.item_l_drul_[d])
+       r.distance_ += r.item_l_drul_[d]->extent (r.item_l_drul_[d], X_AXIS)[-d];
     }
   while (flip (&d) != LEFT);
 
-  r.add_to_cols ();
+  if (r.item_l_drul_[LEFT]
+      && r.item_l_drul_[RIGHT])
+    r.add_to_cols ();
+  
   return SCM_UNSPECIFIED;
 }
 
diff --git a/lily/lyric-phrasing-engraver.cc b/lily/lyric-phrasing-engraver.cc
deleted file mode 100644 (file)
index fb94dde..0000000
+++ /dev/null
@@ -1,253 +0,0 @@
-/*   
-  new-phrasing-engraver.cc --  implement New_phrasing_engraver
-
-source file of the GNU LilyPond music typesetter
-
-(c) 2003--2004 Han-Wen Nienhuys <hanwen@xs4all.nl>
-
- */
-
-
-#include "context.hh"
-#include "engraver.hh"
-#include "note-head.hh"
-#include "lyric-extender.hh"
-#include "item.hh"
-#include "group-interface.hh"
-#include "side-position-interface.hh"
-
-struct Phrasing_association
-{
-  String name_;
-  Link_array<Grob> lyrics_;
-  Link_array<Grob> heads_;
-  Link_array<Spanner> past_extenders_;
-  Link_array<Spanner> new_extenders_;
-  Link_array<Grob> stanza_numbers_;
-
-  
-  bool melisma_;
-  
-  Phrasing_association()
-  {
-    melisma_ = false;
-  }
-};
-
-class Lyric_phrasing_engraver : public Engraver
-{
-public:
-  ~Lyric_phrasing_engraver ();
-  TRANSLATOR_DECLARATIONS(Lyric_phrasing_engraver);
-protected:
-  virtual void acknowledge_grob (Grob_info);
-  virtual void process_acknowledged_grobs ();
-  virtual void stop_translation_timestep ();
-
-private:
-  void add_lyric_phrasing (Grob_info);
-  void add_voice_phrasing (Grob_info);
-  void add_lyric_extender (Grob_info);
-  void add_stanza_number (Grob_info);
-  Phrasing_association *get_phrasing_assoc (String nm);
-  String get_voice_name_for_lyric (Context *tr);
-  Link_array<Phrasing_association> assocs_;
-};
-
-Lyric_phrasing_engraver::Lyric_phrasing_engraver()
-{
-}
-
-void
-Lyric_phrasing_engraver::acknowledge_grob (Grob_info i)
-{
-  Grob *h = i.grob_;
-
-  if (Note_head::has_interface (h))
-    add_voice_phrasing (i);
-  else if (h->internal_has_interface (ly_symbol2scm ("lyric-syllable-interface")))
-    add_lyric_phrasing (i);
-  else if (Lyric_extender::has_interface (h))
-    add_lyric_extender (i);
-  else if (h->internal_has_interface (ly_symbol2scm ("stanza-number-interface")))
-    add_stanza_number (i);
-}
-
-Phrasing_association *
-Lyric_phrasing_engraver::get_phrasing_assoc (String nm)
-{
-  Phrasing_association * a=0;
-  for (int i=0 ; !a && i < assocs_.size (); i++)
-    {
-      if (assocs_[i]->name_ == nm)
-       a = assocs_[i];
-    }
-
-  if (!a)
-    {
-      a = new Phrasing_association ;
-      a->name_ = nm;
-      assocs_.push (a);
-    }
-  return a;
-}
-
-
-
-String
-Lyric_phrasing_engraver::get_voice_name_for_lyric (Context *tr)
-{
-  SCM voice_context = tr->get_property ("associatedVoiceContext");
-  if (Context *vc = unsmob_context (voice_context))
-    {
-      return vc->id_string_;
-    }
-  
-  SCM voice = tr->get_property ("associatedVoice");
-  String nm = tr->id_string_;
-  if (gh_string_p (voice))
-    nm = ly_scm2string (voice);
-  else
-    {
-      int idx = nm.index_last ('-');
-      if (idx >= 0)
-       nm = nm.left_string (idx);
-    }
-
-  return nm;
-}
-
-
-void
-Lyric_phrasing_engraver::add_lyric_extender (Grob_info inf)
-{
-  Context * tr = inf.origin_trans_->daddy_context_;
-  while (tr && !tr->is_alias (ly_symbol2scm ("Lyrics")))
-    tr = tr->daddy_context_;
-
-  if (!tr)
-    return;
-
-  
-  Phrasing_association *a =  get_phrasing_assoc (get_voice_name_for_lyric (tr));
-  a->new_extenders_.push (dynamic_cast<Spanner*> (inf.grob_));  
-}
-
-void
-Lyric_phrasing_engraver::add_stanza_number  (Grob_info inf)
-{
-  Context * tr = inf.origin_trans_->daddy_context_;
-  while (tr && !tr->is_alias (ly_symbol2scm ("Lyrics")))
-    tr = tr->daddy_context_;
-
-  if (!tr)
-    return;
-
-  Phrasing_association *a =  get_phrasing_assoc (get_voice_name_for_lyric (tr));
-  a->stanza_numbers_.push (inf.grob_);
-}
-
-void
-Lyric_phrasing_engraver::add_voice_phrasing (Grob_info inf)
-{
-  Context * tr = inf.origin_trans_->daddy_context_;
-  while (tr && !tr->is_alias (ly_symbol2scm ("Voice")))
-    tr = tr->daddy_context_;
-
-  if (!tr)
-    return;
-
-  Phrasing_association *a =  get_phrasing_assoc (tr->id_string_);
-  a->heads_.push (inf.grob_);
-  a->melisma_ = melisma_busy (inf.origin_trans_);
-}
-
-void
-Lyric_phrasing_engraver::add_lyric_phrasing (Grob_info inf)
-{
-  Context * tr = inf.origin_trans_->daddy_context_;
-  while (tr && !tr->is_alias (ly_symbol2scm ("Lyrics")))
-    tr = tr->daddy_context_;
-
-  if (!tr)
-    return;
-
-
-  Phrasing_association *a =  get_phrasing_assoc (get_voice_name_for_lyric (tr));
-  a->lyrics_.push (inf.grob_);
-  a->past_extenders_.clear ();
-}
-
-void
-Lyric_phrasing_engraver::stop_translation_timestep ()
-{
-  Link_array<Grob> stzs;
-  Link_array<Grob> lyrs;
-  for (int i = assocs_.size ();  i--; )
-    {
-      Phrasing_association * a = assocs_[i];
-      stzs.concat (a->stanza_numbers_);
-      lyrs.concat (a->lyrics_);
-    }
-
-  for(int i= lyrs.size(); i--;)
-    for (int j = stzs.size (); j--;)
-      Side_position_interface::add_support (stzs[j], lyrs[i]);
-    
-  for (int i = assocs_.size ();  i--; )
-    {
-      Phrasing_association * a = assocs_[i];
-
-      a->stanza_numbers_.clear ();
-      a->heads_.clear ();
-      a->lyrics_.clear ();
-      a->past_extenders_.concat (assocs_[i]->new_extenders_) ;
-      a->new_extenders_.clear ();
-    }
-}
-
-void
-Lyric_phrasing_engraver::process_acknowledged_grobs ()
-{
-  for (int i = 0; i < assocs_.size ();  i++)
-    {
-      Phrasing_association * a = assocs_[i];
-      if (! (a->heads_.size()  && (a->lyrics_.size () || a->past_extenders_.size ())))
-       continue;
-
-      Grob *h = a->heads_[0];  
-      Direction alignment = CENTER;
-      if (a->melisma_)
-       alignment = LEFT;
-      
-      for (int j = 0; j < a->lyrics_.size (); j++)
-       {
-         Grob *l = a->lyrics_[j];
-         if (!l->get_parent (X_AXIS))
-           {
-             l->set_parent (h, X_AXIS);
-             if (alignment)
-               l->set_property ("self-alignment-X", gh_int2scm (alignment));
-           }
-       }
-
-      for (int j = a->past_extenders_.size(); j--;)
-       Pointer_group_interface::add_grob (a->past_extenders_[j],ly_symbol2scm ("heads"), h);
-    }
-}
-
-Lyric_phrasing_engraver::~Lyric_phrasing_engraver ()
-{
-  for (int i =assocs_.size(); i--;)
-    delete assocs_[i];
-}
-
-ENTER_DESCRIPTION(Lyric_phrasing_engraver,
-                 "This engraver combines note heads and lyrics for alignment. ",
-                 "",
-                 "",
-                 "stanza-number-interface lyric-syllable-interface "
-                 "note-head-interface lyric-extender-interface",
-                 "associatedVoice",
-                 "");
-
index ce14a2909e7605aee2e7465d3eb436427d05b43d..1ac8032102cf3281122ee168f26f4606e632859c 100644 (file)
@@ -36,7 +36,7 @@ Melisma_translator::try_music (Music *m)
 {
   if (m->is_mus_type ("melisma-playing-event"))
     {
-      return melisma_busy (this);
+      return melisma_busy (daddy_context_);
     }
   else if (m->is_mus_type ("melisma-span-event"))
     {
index cafb9a365abe65c56cc01cc2a0a15fe48b2674bb..bcc942e095ac9625a18a27b1c285ed06c03ba707 100644 (file)
@@ -15,7 +15,6 @@
 #include "ly-smobs.icc"
 
 
-SCM ly_deep_mus_copy (SCM);
 
 bool
 Music::internal_is_music_type (SCM k)const
index 53acda5cdd6d11403eb25fc7027d25556abc2216..007aa9d1ee6b8cea30d742a3d46127511b472e8d 100644 (file)
@@ -85,6 +85,7 @@ static Keyword_ent the_key_tab[]={
   {"times", TIMES},
   {"translator", TRANSLATOR},
   {"transpose", TRANSPOSE},
+  {"transposition", TRANSPOSITION},
   {"type", TYPE},
   {"unset", UNSET},
   {"with", WITH},
index 046e6935acf32b03450aa18eb134300b932bff41..ab6f6a188735bb621ddaa89efea95a6bb78a1c77 100644 (file)
@@ -37,11 +37,11 @@ Note_performer::create_audio_elements ()
 {
   if (note_evs_.size ())
     {
-      int transposing_i = 0;
-      //urg
-      SCM prop = get_property ("transposing");
-      if (gh_number_p (prop)) 
-       transposing_i = gh_scm2int (prop);
+      int transposing = 0;
+
+      SCM prop = get_property ("instrumentTransposition");
+      if (unsmob_pitch (prop)) 
+       transposing = unsmob_pitch (prop)->semitone_pitch ();
 
       while (note_evs_.size ())
        {
@@ -50,7 +50,7 @@ Note_performer::create_audio_elements ()
 
          if (Pitch * pitp = unsmob_pitch (pit))
            {
-             Audio_note* p = new Audio_note (*pitp,  n->get_length (), transposing_i);
+             Audio_note* p = new Audio_note (*pitp,  n->get_length (), transposing);
              Audio_element_info info (p, n);
              announce_element (info);
              notes_.push (p);
index 666963b1f75bb967fd9edf03d424f7988622fc8f..1af8d751382bacc33c93aac83b74d1e8a5f53fe8 100644 (file)
@@ -301,6 +301,7 @@ yylex (YYSTYPE *s,  void * v)
 %token TIME_T
 %token TRANSLATOR
 %token TRANSPOSE
+%token TRANSPOSITION
 %token TYPE
 %token UNSET
 %token WITH
@@ -1363,19 +1364,19 @@ command_element:
 
                $$ = skip;
        }
-       | QUOTE duration_length STRING {
+       | QUOTE STRING duration_length {
                SCM tab = THIS->lexer_->lookup_identifier ("musicQuotes");
                SCM evs =  SCM_EOL;
                if (scm_hash_table_p (tab) == SCM_BOOL_T)
                { 
-                       SCM key = $3; // use symbol? 
+                       SCM key = $2; // use symbol? 
                        evs = scm_hash_ref (tab, key, SCM_BOOL_F);
                }
                Music * quote = 0;
-               if (scm_vector_p (evs) == SCM_BOOL_T)
+               if (gh_vector_p (evs))
                {
                        quote = MY_MAKE_MUSIC("QuoteMusic");
-                       quote->set_property ("duration", $2);
+                       quote->set_property ("duration", $3);
                        quote->set_property ("quoted-events", evs);
                } else {
                        THIS->here_input ().warning (_f ("Can\'t find music")); 
@@ -1420,6 +1421,13 @@ command_element:
                $$ = MY_MAKE_MUSIC("BarCheck");
                $$->set_spot (THIS->here_input ());
        }
+       | TRANSPOSITION pitch {
+               $$ = set_property_music (ly_symbol2scm ("instrumentTransposition"),
+                                       $2);
+               $$->set_spot (THIS-> here_input ());
+               $$ = context_spec_music (ly_symbol2scm ("Staff"), SCM_UNDEFINED,
+                       $$ , SCM_EOL);
+       }
        | BAR STRING                    {
                Music *t = set_property_music (ly_symbol2scm ("whichBar"), $2);
 
index 266ca9ed1a25838b4cf88c13f98d3f6ba505b14b..8b4a7d59ec00e0aa7658bfca99de97ba2117ba8f 100644 (file)
@@ -27,15 +27,24 @@ public:
   int event_idx_;
   int end_idx_ ;
 
+  SCM transposed_musics_;
+  
   DECLARE_SCHEME_CALLBACK(constructor, ()); 
 
 protected:
+  virtual void derived_mark ();
   virtual void construct_children ();
   virtual Moment pending_moment () const;
   virtual void process (Moment);
   virtual bool ok () const;
 };
 
+void
+Quote_iterator::derived_mark ()
+{
+  scm_gc_mark (transposed_musics_ );
+}
+
 Quote_iterator::Quote_iterator ()
 {
   event_vector_ = SCM_EOL;
@@ -63,7 +72,7 @@ binsearch_scm_vector (SCM vec, SCM key, bool (*is_less)(SCM a,SCM b))
   {
     int cmp = (lo + hi) / 2;
 
-      SCM when = gh_car (SCM_VECTOR_REF(vec, cmp));
+      SCM when = gh_caar (SCM_VECTOR_REF(vec, cmp));
       bool result =  (*is_less) (key, when);
       if (result)
           hi = cmp;
@@ -91,7 +100,7 @@ Quote_iterator::construct_children ()
   start_moment_ = now;
   event_vector_ = get_music ()->get_property ("quoted-events");
 
-  if (scm_vector_p (event_vector_) == SCM_BOOL_T)
+  if (gh_vector_p (event_vector_))
     {
       event_idx_ = binsearch_scm_vector (event_vector_, now.smobbed_copy (), &moment_less);
       end_idx_ = binsearch_scm_vector (event_vector_, stop.smobbed_copy (), &moment_less);
@@ -110,7 +119,7 @@ Moment
 Quote_iterator::pending_moment () const
 {
   SCM entry = SCM_VECTOR_REF (event_vector_, event_idx_);
-  return *unsmob_moment (gh_car (entry)) - start_moment_;
+  return *unsmob_moment (gh_caar (entry)) - start_moment_;
 }
 
 
@@ -124,7 +133,7 @@ Quote_iterator::process (Moment m)
     {
       entry = SCM_VECTOR_REF (event_vector_, event_idx_);
 
-      Moment em = *unsmob_moment (gh_car (entry));
+      Moment em = *unsmob_moment (gh_caar (entry));
 
       if (em > m)
        return ;
@@ -137,6 +146,9 @@ Quote_iterator::process (Moment m)
 
   if (gh_pair_p (entry))
     {
+      Pitch * quote_pitch = unsmob_pitch (gh_cdar (entry));
+      Pitch * me_pitch = unsmob_pitch (get_outlet ()->get_property ("instrumentTransposition"));
+      
       for (SCM s = gh_cdr (entry); gh_pair_p (s); s = gh_cdr (s))
        {
          SCM ev_acc = gh_car (s);
@@ -145,6 +157,24 @@ Quote_iterator::process (Moment m)
          Music * mus = unsmob_music (gh_car (ev_acc));
          if (mus)
            {
+             if (quote_pitch || me_pitch)
+               {
+                 Pitch qp, mp;
+                 if (quote_pitch)
+                   qp = *quote_pitch;
+                 if (me_pitch)
+                   mp = *me_pitch;
+
+                 Pitch diff = interval (mp, qp);
+
+                 SCM copy = ly_deep_mus_copy (mus->self_scm ());
+                 mus = unsmob_music (copy);
+                 transposed_musics_ = gh_cons (copy, transposed_musics_);
+                 
+                 mus->transpose (diff);
+               }
+
+             
              bool b = get_outlet ()->try_music (mus);
       
              if (!b)
index c314bb736faa2d9d8ede051897c67c203a199eee..0b8b87da00031f9c35bcb3f97eb3de82ac016ef6 100644 (file)
@@ -13,6 +13,7 @@
 
 class Recording_group_engraver : public Engraver_group_engraver
 {
+  void start ();
 public:
   TRANSLATOR_DECLARATIONS(Recording_group_engraver);
   virtual bool try_music (Music *m);
@@ -27,8 +28,7 @@ void
 Recording_group_engraver::initialize ()
 {
   Engraver_group_engraver::initialize ();
-  accumulator_ = gh_cons (gh_cons (now_mom (). smobbed_copy (), SCM_EOL),
-                         SCM_EOL);
+  start ();
 }
 
 Recording_group_engraver::Recording_group_engraver()
@@ -46,8 +46,23 @@ Recording_group_engraver::start_translation_timestep ()
     start_translation_timestep(), since start_translation_timestep()
     isn't called on the first time-step.
    */
+  start () ;
+}
+
+void
+Recording_group_engraver::start ()
+{
+  if (!gh_pair_p (accumulator_))
+    accumulator_ = gh_cons (SCM_EOL, SCM_EOL);
   if (!gh_pair_p (gh_car (accumulator_)))
-    scm_set_car_x (accumulator_, gh_cons (now_mom ().smobbed_copy (), SCM_EOL));
+    {
+      /*
+       Need to store transposition for every moment; transposition changes during pieces.
+       */
+      scm_set_car_x (accumulator_, gh_cons (gh_cons (now_mom ().smobbed_copy (),
+                                                    get_property ("instrumentTransposition")),
+                                                    SCM_EOL));
+    }
 }
 
 void
index 39aebe4274118d878a3d7c59955bb0530c99359a..8f6de86a97e20982b02b4dfbb6f29f07cee991f0 100644 (file)
@@ -21,9 +21,9 @@
        \consists "Bar_engraver"
 % Bar_engraver must be first so default bars aren't overwritten
 % with empty ones.
+       
        \consists "Font_size_engraver"
 
-%      \consists "Repeat_engraver"
        \consists "Volta_engraver"
        \consists "Separating_line_group_engraver"      
        \consists "Dot_column_engraver"
@@ -39,8 +39,6 @@
        \consists "Accidental_engraver"
        \consists "Piano_pedal_engraver"
        \consists "Instrument_name_engraver"
-       \consists "Grob_pq_engraver"
-       \consists "Forbid_line_break_engraver"
        \consists "String_number_engraver"
        \consistsend "Axis_group_engraver"
 
     \consists "Multi_measure_rest_engraver"
     \consists "Text_spanner_engraver"
     \consists "Grob_pq_engraver"
+    \consists "Forbid_line_break_engraver"
 
     \consists "Note_head_line_engraver"
     \consists "Glissando_engraver"
@@ -420,7 +419,7 @@ AncientRemoveEmptyStaffContext = \translator {
     \consists "Break_align_engraver"
     \consists "Spacing_engraver"
     \consists "Vertical_align_engraver"
-    \consists "Lyric_phrasing_engraver"
+    \consists "Stanza_number_align_engraver"
     \consists "Bar_number_engraver"
     \consists "Span_arpeggio_engraver"
 
index 22c2b77848842d501f708daf8061d3eb5b74365b..1fece80f4d472bb29d6977aa04d188f89b69fe8f 100644 (file)
@@ -187,6 +187,7 @@ selector for tab notation.")
 @code{instrument} property labels the staff in the first system, and
 the @code{instr} property labels following lines.")
      (instrumentEqualizer ,procedure? "[DOCUMENT-ME]")
+     (instrumentTransposition ,ly:pitch? "Define the transposition of the instrument. This is used to transpose the MIDI output, and @code{\\quote}s.")
 
      (instrumentSupport ,list? "list of grobs to attach instrument name
 to.")
@@ -315,7 +316,6 @@ is a 4/4 time signature.")
 Switch off for cadenzas.")
      (tonic ,ly:pitch?
            "The tonic of the current scale")
-     (transposing ,integer? "Transpose the MIDI output.  Set this property to the number of half-steps to transpose by.")
 
      (tremoloFlags ,integer? "Number of tremolo flags to add if none is specified.")
 
index fcca7a56b85e36b06ee4de21ea9a598f54f7ab41..a4c21b7767dedd72054397fd790b880490a49908 100644 (file)
@@ -10,6 +10,7 @@
 (define-class <Voice-state> ()
   (event-list #:init-value '() #:accessor events #:init-keyword #:events)
   (when-moment #:accessor when #:init-keyword #:when)
+  (tuning #:accessor tuning #:init-keyword #:tuning)
   (split-index #:accessor split-index)
   (vector-index)
   (state-vector)
@@ -81,7 +82,8 @@
         (map
          (lambda (v)
            (make <Voice-state>
-             #:when (car v)
+             #:when (caar v)
+             #:tuning (cdar v)
              #:events (map car (cdr v))
              ))
          evl))))
@@ -580,8 +582,9 @@ the mark when there are no spanners active."
     (if (null? event-list)
        acc
        (let*
-           ((evs (map car (cdar event-list)))
-            (now (caar event-list))
+           ((now-tun (caar event-list))
+            (evs (map car (cdar event-list)))
+            (now (car now-tun))
             (notes (filter (lambda (x)
                              (equal? (ly:music-property  x 'name) 'NoteEvent))
                              evs))
index 9d93613efb6820bae90694026cdb678fd4082c04..f8733826621aec75e09c051cc24701d421a18a5f 100644 (file)
@@ -1938,6 +1938,38 @@ def conv (str):
        return str
 
 conversions.append (((2,1,26), conv, """More Scheme function renaming"""))
+
+def conv (str):
+       def subst (m):
+               g = string.atoi (m.group (2))
+               o = g / 12
+               g -= o * 12
+               if g <  0:
+                       g += 12
+                       o -= 1
+
+
+               lower_pitches = filter (lambda x : x <= g, [0, 2, 4, 5, 7, 9, 11, 12])
+               s = len (lower_pitches) -1 
+               a = g - lower_pitches [-1]
+
+
+               print s , lower_pitches, g, a, s 
+               str = 'cdefgab' [s]
+               str += ['eses', 'es', '', 'is', 'isis'][a + 2]
+               if o < 0:
+                       str += ',' * (-o - 1)
+               elif o >= 0:
+                       str += "'" * (o + 1)
+                       
+               return '\\tuning %s ' % str
+
+       
+       str = re.sub (r"\\set ([A-Za-z]+\s*\.\s*)?transposing\s*=\s*#([-0-9]+)",
+                     subst, str)
+       return str
+
+conversions.append (((2,1,26), conv, """property transposing -> tuning"""))
 ################################
 #      END OF CONVERSIONS      
 ################################