From 0a0f8863aa70cf42b69ca374cbb12c061ccd0547 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Mon, 1 Jul 2002 23:52:24 +0000 Subject: [PATCH] '' --- ChangeLog | 7 +++++ input/template/satb.ly | 51 +++++++++++++++++++++++++++++++++ lily/ambitus-engraver.cc | 61 ++++++++++++++++++++++------------------ lily/ambitus.cc | 25 ++++++++++++---- 4 files changed, 112 insertions(+), 32 deletions(-) create mode 100644 input/template/satb.ly diff --git a/ChangeLog b/ChangeLog index a0c23596c0..6546837642 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2002-07-02 Juergen Reuter + + * lily/ambitus-engraver.cc, lily/ambitus.cc: Various bugfixes: + avoid segfault on undefined ambitus pitch; avoid wasteful creation + of pitch smobs; defer computation of centralCPosition beyond first + timestep to catch also clefs outside of the current voice context. + 2002-07-02 Han-Wen * input/template/satb.ly: new file diff --git a/input/template/satb.ly b/input/template/satb.ly new file mode 100644 index 0000000000..3c2369616f --- /dev/null +++ b/input/template/satb.ly @@ -0,0 +1,51 @@ + +%{ + + Example template for a SATB vocal score. + +%} + +sopMusic = \notes \relative c'' { c4 c [c8( )b] c4 } +sopWords = \lyrics { hi4 hi hi hi } + +altoMusic = \notes \relative c' { e4 f d e } +altoWords =\lyrics { ha4 ha ha ha } + +tenorMusic = \notes \relative c' { g4 a f g } +tenorWords = \lyrics { hu4 hu hu hu } + +bassMusic = \notes \relative c { c4 c g c } +bassWords = \lyrics { ho4 ho ho ho } + +\score { \notes + \context StaffGroup < + \property Score.automaticMelismata = ##t + \context Lyrics = sopLyrs { s1 } + \context Staff = women { s1 } + \context Lyrics = altoLyrs { s1 } + \context Lyrics = tenorLyrs { s1 } + \context Staff = men {\clef bass s1 } + \context Lyrics = bassLyrs { s1 } + \addlyrics + \context Staff = women \context Voice = VA { \voiceOne \sopMusic } + \context Lyrics = sopLyrs { \sopWords} + \addlyrics + \context Staff = women \context Voice = VB { \voiceTwo \altoMusic } + \context Lyrics = altoLyrs { \altoWords} + \addlyrics + \context Staff = men \context Voice = VA { \voiceOne \tenorMusic } + \context Lyrics = tenorLyrs { \tenorWords} + \addlyrics + \context Staff = men \context Voice = VB { \voiceTwo \bassMusic } + \context Lyrics = bassLyrs { \bassWords} + + > + \paper { + \translator { + + % a little smaller so lyrics can be closer to the staff. + \StaffContext + minimumVerticalExtent = #'(-3 . 3) + } + } +} diff --git a/lily/ambitus-engraver.cc b/lily/ambitus-engraver.cc index fb0af0286b..85dbbd46b8 100644 --- a/lily/ambitus-engraver.cc +++ b/lily/ambitus-engraver.cc @@ -64,10 +64,9 @@ class Ambitus_engraver : public Engraver { public: TRANSLATOR_DECLARATIONS(Ambitus_engraver); - virtual void start_translation_timestep (); virtual void acknowledge_grob (Grob_info); - virtual void create_grobs (); virtual void stop_translation_timestep (); + virtual void finalize (); private: void create_ambitus (); @@ -90,6 +89,14 @@ void Ambitus_engraver::stop_translation_timestep () { if (!ambitus_p_) { + // Create ambitus not before stopping timestep. centralCPosition + // will then be the same as that for the first timestep. + // + // TODO: is this really a good idea? At least, creating the + // ambitus in start_translation_timestep is a *bad* idea, since we + // may then oversee a clef that is defined in a staff context if + // we are in a voice context; centralCPosition would then be + // assumed to be 0. create_ambitus (); } if (ambitus_p_ && isActive) @@ -97,27 +104,10 @@ Ambitus_engraver::stop_translation_timestep () SCM key_signature = get_property ("keySignature"); ambitus_p_->set_grob_property ("keySignature", key_signature); typeset_grob (ambitus_p_); - //ambitus_p_ = 0; isActive = 0; } } -void -Ambitus_engraver::start_translation_timestep () -{ - if (!ambitus_p_) { - create_ambitus (); - } -} - -void -Ambitus_engraver::create_grobs () -{ - if (!ambitus_p_) { - create_ambitus (); - } -} - void Ambitus_engraver::acknowledge_grob (Grob_info info) { @@ -140,22 +130,14 @@ Ambitus_engraver::acknowledge_grob (Grob_info info) // not yet init'd; use current pitch to init min/max pitch_min = pitch; pitch_max = pitch; - ambitus_p_->set_grob_property ("pitch-min", - pitch_min.smobbed_copy ()); - ambitus_p_->set_grob_property ("pitch-max", - pitch_max.smobbed_copy ()); } else if (Pitch::compare (pitch, pitch_max) > 0) // new max? { pitch_max = pitch; - ambitus_p_->set_grob_property ("pitch-max", - pitch_max.smobbed_copy ()); } else if (Pitch::compare (pitch, pitch_min) < 0) // new min? { pitch_min = pitch; - ambitus_p_->set_grob_property ("pitch-min", - pitch_min.smobbed_copy ()); } } } @@ -172,6 +154,31 @@ Ambitus_engraver::create_ambitus () announce_grob (ambitus_p_, SCM_EOL); } +void +Ambitus_engraver::finalize () +{ + if (ambitus_p_) + { + if (Pitch::compare (pitch_min, pitch_max) <= 0) + { + ambitus_p_->set_grob_property ("pitch-min", + pitch_min.smobbed_copy ()); + ambitus_p_->set_grob_property ("pitch-max", + pitch_max.smobbed_copy ()); + } + else // have not seen any pitch, so forget about the ambitus + { + // Do not print a warning on empty ambitus range, since this + // most probably arises from an empty voice, such as shared + // global timesig/clef definitions. +#if 0 + ambitus_p_->warning("empty ambitus range [ignored]"); +#endif + ambitus_p_->suicide(); + } + } +} + ENTER_DESCRIPTION(Ambitus_engraver, /* descr */ "", /* creats*/ "Ambitus", diff --git a/lily/ambitus.cc b/lily/ambitus.cc index ccc7ba3318..c09f557f1b 100644 --- a/lily/ambitus.cc +++ b/lily/ambitus.cc @@ -146,15 +146,30 @@ Ambitus::brew_molecule (SCM smob) return SCM_EOL; } + int p_min, p_max; Pitch *pitch_min = unsmob_pitch (me->get_grob_property ("pitch-min")); - int p_min = pitch_min->steps (); + if (!pitch_min) + { + me->programming_error("Ambitus: pitch_min undefined; assuming 0"); + p_min = 0; + } + else + { + p_min = pitch_min->steps (); + } Pitch *pitch_max = unsmob_pitch (me->get_grob_property ("pitch-max")); - int p_max = pitch_max->steps (); + if (!pitch_max) + { + me->programming_error("Ambitus: pitch_max undefined; assuming 0"); + p_max = 0; + } + else + { + p_max = pitch_max->steps (); + } if (p_min > p_max) { - String message = "Ambitus: no range to output"; - me->warning (_ (message.ch_C ())); - return SCM_EOL; + me->programming_error ("Ambitus: reverse range"); } SCM c0 = me->get_grob_property ("centralCPosition"); -- 2.39.5