From ea12e68fee5bd03385760efc9ad5cebbd58bbb72 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 3 Nov 2002 17:45:13 +0000 Subject: [PATCH] *** empty log message *** --- Documentation/user/tutorial.itely | 31 +++-- lily/new-tie-engraver.cc | 190 ++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 lily/new-tie-engraver.cc diff --git a/Documentation/user/tutorial.itely b/Documentation/user/tutorial.itely index 96b6ddbcbd..ab1db83971 100644 --- a/Documentation/user/tutorial.itely +++ b/Documentation/user/tutorial.itely @@ -345,7 +345,7 @@ You can also print from the command line by executing: To run LilyPond, input a text file, then run the command @code{ly2dvi} on that file. The resulting files are either DVI or PostScript, and can -be viewed with @code{xdvi} (unix) and ghostview (unix and windows) +be viewed with @code{xdvi} (Unix) and ghostview (Unix and Windows) respectively. The following table summarizes the constructs that were discussed in the previous two sections. @@ -456,9 +456,14 @@ g'4-~ g' a'2-~ a'4 @end lilypond @end quotation @separate -A tilde is different from a tie. A tie simply makes the first note +A tie is different from a slur. A tie simply makes the first note sound longer, and can only be used on pairs of notes with the same -pitch. +pitch. Slurs indicate the articulations of notes, and can be used on +larger groups of notes. Slurs and ties are also nested in practice: +@lilypond[fragment, relative=1] +c2-~-( c8 fis fis4 ~ fis2 g2-) +@end lilypond + The key signature is set with the command ``@code{\key}''. One caution word of caution: you need to specify whether the key is @@ -861,7 +866,7 @@ r4 <>8-\>-( <> <> <>8-\!-\) \property Staff.TimeSignature = \turnOff \property Staff.autoBeaming = ##f \property Staff.Clef = \turnOff -c( d )e +c-( d e-) @end lilypond @@ -873,7 +878,7 @@ c( d )e \property Staff.TimeSignature = \turnOff \property Staff.autoBeaming = ##f \property Staff.Clef = \turnOff -c\( c() d \)e +c-\( c-( d-) e-\) @end lilypond @@ -885,7 +890,7 @@ c\( c() d \)e \property Staff.TimeSignature = \turnOff \property Staff.autoBeaming = ##f \property Staff.Clef = \turnOff -[a8 b] +a8-[ b-] @end lilypond @@ -937,15 +942,15 @@ a\< a \!a \property Staff.TimeSignature = \turnOff \property Staff.autoBeaming = ##f \property Staff.Clef = \turnOff -a\> a \!a +a-\> a a-\! @end lilypond -@item @code{< >} +@item @code{<< >>} @tab chord @tab @lilypond[fragment, relative 1] -\context Voice +<> @end lilypond @end multitable @@ -1097,8 +1102,8 @@ melody = \notes \relative c' @{ \partial 8 \key c \minor g8 | - c4 c8 d [es () d] c4 | f4 f8 g [es() d] c g | - c4 c8 d [es () d] c4 | d4 es8 d c4. + c4 c8 d es-[ -( d-]-) c4 | f4 f8 g es-[-( d-)-] c g | + c4 c8 d es-[ -( d-]-) c4 | d4 es8 d c4. \bar "|." @} @@ -1130,8 +1135,8 @@ melody = \notes \relative c' { \partial 8 \key c \minor g8 | - c4 c8 d [es () d] c4 | f4 f8 g [es() d] c g | - c4 c8 d [es () d] c4 | d4 es8 d c4. + c4 c8 d es-[ -( d-)-] c4 | f4 f8 g es-(-[ d-)-] c g | + c4 c8 d es-(-[ d-]-) c4 | d4 es8 d c4. \bar "|." } diff --git a/lily/new-tie-engraver.cc b/lily/new-tie-engraver.cc new file mode 100644 index 0000000000..8ee6d218ff --- /dev/null +++ b/lily/new-tie-engraver.cc @@ -0,0 +1,190 @@ +/* + new-tie-engraver.cc -- implement Tie_engraver + + source file of the GNU LilyPond music typesetter + + (c) 1998--2002 Han-Wen Nienhuys + + */ + +#include "event.hh" +#include "tie.hh" +#include "translator-group.hh" +#include "spanner.hh" +#include "tie-column.hh" +#include "engraver.hh" +#include "item.hh" +#include "grob-pitch-tuple.hh" +#include "warn.hh" +#include "note-head.hh" + +/** + Manufacture ties. Acknowledge noteheads, and put them into a + priority queue. If we have a TieEvent, connect the notes that finish + just at this time, and note that start at this time. + + TODO: Remove the dependency on musical info. We should tie on the + basis of position and duration-log of the heads (not of the events). + + TODO: support sparseTies. + + TODO: melismata will fuck up now: + + < { c8 ~ c8 } + { c16 c c c } > + + melisma is after the 2nd 8th note, but will now be signaled as + lasting till the 3rd 16th. +*/ +class New_tie_engraver : public Engraver +{ + Music *event_; + Music *last_event_; + Link_array now_heads_; + Link_array heads_to_tie_; + Link_array ties_; + + Spanner * tie_column_; + + +protected: + virtual void stop_translation_timestep (); + virtual void acknowledge_grob (Grob_info); + virtual bool try_music (Music*); + virtual void process_acknowledged_grobs (); + void typeset_tie (Grob*); +public: + TRANSLATOR_DECLARATIONS(New_tie_engraver); +}; + + + +New_tie_engraver::New_tie_engraver () +{ + event_ = 0; + last_event_ = 0; + tie_column_ = 0; +} + + +bool +New_tie_engraver::try_music (Music *mus) +{ + if (mus->is_mus_type ("new-tie-event")) + { + event_ = mus; + } + + if (event_) + { + SCM m = get_property ("automaticMelismata"); + bool am = gh_boolean_p (m) &&gh_scm2bool (m); + if (am) + { + daddy_trans_->set_property ("tieMelismaBusy", m ? SCM_BOOL_T : SCM_BOOL_F); + } + } + return true; +} + +void +New_tie_engraver::acknowledge_grob (Grob_info i) +{ + if (Note_head::has_interface (i.grob_)) + { + Grob * h = i.grob_; + now_heads_.push (h); + for (int i=heads_to_tie_.size (); i--;) + { + Grob *th = heads_to_tie_[i]; + int staff_pos = gh_scm2int (h->get_grob_property ("staff-position")); + int left_staff_pos = gh_scm2int (th->get_grob_property ("staff-position")); + if (staff_pos == left_staff_pos) + { + Grob * p = new Spanner (get_property ("Tie")); + Tie::set_interface (p); // cannot remove yet! + + Tie::set_head (p, LEFT, th); + Tie::set_head (p, RIGHT, h); + + ties_.push (p); + announce_grob(p, last_event_->self_scm()); + } + } + } +} + +void +New_tie_engraver::process_acknowledged_grobs () +{ + if (ties_.size () > 1 && !tie_column_) + { + tie_column_ = new Spanner (get_property ("TieColumn")); + + for (int i = ties_.size (); i--;) + Tie_column::add_tie (tie_column_,ties_ [i]); + + announce_grob(tie_column_, SCM_EOL); + } +} + + +void +New_tie_engraver::stop_translation_timestep () +{ + + if (ties_.size ()) + { + heads_to_tie_.clear (); + for (int i=0; i< ties_.size (); i++) + { + typeset_tie (ties_[i]); + } + + ties_.clear(); + last_event_ = 0; + if (tie_column_) + { + typeset_grob (tie_column_); + tie_column_ =0; + } + } + + if (event_) + { + heads_to_tie_ = now_heads_; + last_event_ = event_; + } + event_ = 0; + now_heads_.clear (); +} + +void +New_tie_engraver::typeset_tie (Grob *her) +{ + if (! (Tie::head (her,LEFT) && Tie::head (her,RIGHT))) + warning (_ ("lonely tie")); + + Direction d = LEFT; + Drul_array new_head_drul; + new_head_drul[LEFT] = Tie::head (her,LEFT); + new_head_drul[RIGHT] = Tie::head (her,RIGHT); + do { + if (!Tie::head (her,d)) + new_head_drul[d] = Tie::head (her, (Direction)-d); + } while (flip (&d) != LEFT); + + index_set_cell (her->get_grob_property ("heads"), LEFT, new_head_drul[LEFT]->self_scm ()); + index_set_cell (her->get_grob_property ("heads"), RIGHT, new_head_drul[RIGHT]->self_scm ()); + + typeset_grob (her); +} + + +ENTER_DESCRIPTION(New_tie_engraver, +/* descr */ "Generate ties between noteheads of equal pitch.", +/* creats*/ "Tie TieColumn", +/* accepts */ "new-tie-event", +/* acks */ "rhythmic-head-interface", +/* reads */ "tieMelismaBusy", +/* write */ ""); -- 2.39.2