From cc676c5aadd45985251b5d60fa23eed1ed98f6e6 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Wed, 2 Aug 2006 21:41:15 +0000 Subject: *** empty log message *** --- ChangeLog | 3 + lily/auto-beam-engraver.cc | 42 +++--- lily/beam-engraver.cc | 50 +++----- lily/breathing-sign-engraver.cc | 15 ++- lily/chord-name-engraver.cc | 47 +++---- lily/chord-tremolo-engraver.cc | 48 ++++--- lily/cluster-engraver.cc | 26 ++-- lily/completion-note-heads-engraver.cc | 66 +++++----- lily/dispatcher.cc | 3 +- lily/drum-note-engraver.cc | 32 ++--- lily/dynamic-engraver.cc | 70 +++++----- lily/extender-engraver.cc | 21 ++- lily/fall-engraver.cc | 21 ++- lily/figured-bass-engraver.cc | 124 +++++++++--------- lily/fingering-engraver.cc | 31 ++--- lily/glissando-engraver.cc | 21 ++- lily/gregorian-ligature-engraver.cc | 17 +-- lily/horizontal-bracket-engraver.cc | 44 +++---- lily/hyphen-engraver.cc | 22 ++-- lily/include/gregorian-ligature-engraver.hh | 5 +- lily/include/ligature-engraver.hh | 6 +- lily/include/music.hh | 3 + lily/include/paper-column-engraver.hh | 7 +- lily/include/score-engraver.hh | 1 - lily/include/stream-event.hh | 12 +- lily/include/translator.icc | 6 + lily/key-engraver.cc | 36 +++--- lily/laissez-vibrer-engraver.cc | 18 ++- lily/ligature-engraver.cc | 16 +-- lily/lyric-engraver.cc | 21 ++- lily/mark-engraver.cc | 21 +-- lily/melisma-translator.cc | 4 +- lily/mensural-ligature-engraver.cc | 15 ++- lily/multi-measure-rest-engraver.cc | 40 +++--- lily/music.cc | 46 ++++--- lily/note-heads-engraver.cc | 32 ++--- lily/note-name-engraver.cc | 21 ++- lily/output-property-engraver.cc | 38 +++--- lily/paper-column-engraver.cc | 32 +++-- lily/parser.yy | 2 +- lily/part-combine-engraver.cc | 30 +++-- lily/percent-repeat-engraver.cc | 23 ++-- lily/phrasing-slur-engraver.cc | 48 +++---- lily/piano-pedal-engraver.cc | 192 ++++++++++++++++++---------- lily/piano-pedal-performer.cc | 12 +- lily/quote-iterator.cc | 32 +++-- lily/recording-group-engraver.cc | 3 + lily/repeat-tie-engraver.cc | 15 +-- lily/rest-engraver.cc | 27 ++-- lily/score-engraver.cc | 9 -- lily/script-engraver.cc | 51 ++++---- lily/simple-closure.cc | 2 +- lily/slash-repeat-engraver.cc | 43 +++---- lily/slur-engraver.cc | 39 +++--- lily/spacing-engraver.cc | 33 ++--- lily/staff-symbol-engraver.cc | 29 +++-- lily/stem-engraver.cc | 33 +++-- lily/tab-note-heads-engraver.cc | 53 ++++---- lily/text-engraver.cc | 25 ++-- lily/text-spanner-engraver.cc | 25 ++-- lily/tie-engraver.cc | 20 ++- lily/time-scaled-music-iterator.cc | 4 +- lily/translator.cc | 49 ++++++- lily/trill-spanner-engraver.cc | 22 ++-- lily/tuplet-engraver.cc | 43 +++---- lily/vaticana-ligature-engraver.cc | 17 +++ ly/declarations-init.ly | 5 +- ly/engraver-init.ly | 1 - ly/performer-init.ly | 1 - scm/autochange.scm | 15 +-- scm/define-event-classes.scm | 110 +++++++++++++--- scm/define-music-display-methods.scm | 4 +- scm/define-music-types.scm | 34 ++--- scm/music-functions.scm | 4 + scm/part-combiner.scm | 101 ++++++++++----- 75 files changed, 1164 insertions(+), 1075 deletions(-) diff --git a/ChangeLog b/ChangeLog index ad63d8d065..6be3bec081 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,8 @@ 2006-08-02 Han-Wen Nienhuys + * lily/*-engraver.cc: convert all try_music functions in + *-engraver.cc. (Patch by Erik S.; please elaborate) + * input/test/instrument-name-align.ly: update version. 2006-08-02 Mats Bengtsson diff --git a/lily/auto-beam-engraver.cc b/lily/auto-beam-engraver.cc index 5ced1d2cfe..26aef17543 100644 --- a/lily/auto-beam-engraver.cc +++ b/lily/auto-beam-engraver.cc @@ -6,17 +6,18 @@ (c) 1999--2006 Jan Nieuwenhuizen */ -#include "engraver.hh" +#include "bar-line.hh" #include "beaming-pattern.hh" #include "beam.hh" -#include "stem.hh" -#include "warn.hh" -#include "bar-line.hh" -#include "rest.hh" -#include "item.hh" -#include "spanner.hh" #include "context.hh" #include "duration.hh" +#include "engraver.hh" +#include "item.hh" +#include "rest.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "stem.hh" +#include "warn.hh" #include "translator.icc" @@ -28,7 +29,6 @@ protected: void stop_translation_timestep (); void start_translation_timestep (); void process_music (); - virtual bool try_music (Music *); virtual void finalize (); virtual void derived_mark () const; @@ -36,6 +36,7 @@ protected: DECLARE_ACKNOWLEDGER (beam); DECLARE_ACKNOWLEDGER (bar_line); DECLARE_ACKNOWLEDGER (stem); + DECLARE_TRANSLATOR_LISTENER (beam_forbid); void process_acknowledged (); @@ -50,7 +51,7 @@ private: bool is_same_grace_state (Grob *e); void typeset_beam (); - Music *forbid_; + Stream_event *forbid_; /* shortest_mom is the shortest note in the beam. */ @@ -128,16 +129,11 @@ Auto_beam_engraver::Auto_beam_engraver () beam_settings_ = SCM_EOL; } -bool -Auto_beam_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Auto_beam_engraver, beam_forbid); +void +Auto_beam_engraver::listen_beam_forbid (Stream_event *ev) { - if (m->is_mus_type ("beam-forbid-event")) - { - forbid_ = m; - return true; - } - - return false; + forbid_ = ev; } bool @@ -335,8 +331,8 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) { check_bar_property (); Item *stem = dynamic_cast (info.grob ()); - Music *m = info.ultimate_music_cause (); - if (!m->is_mus_type ("rhythmic-event")) + Stream_event *ev = info.ultimate_event_cause (); + if (!ev->in_event_class ("rhythmic-event")) { programming_error ("stem must have rhythmic structure"); return; @@ -359,7 +355,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) return; } - int durlog = unsmob_duration (m->get_property ("duration"))->duration_log (); + int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log (); if (durlog <= 2) { @@ -375,7 +371,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) if (bool (beam_start_location_.grace_part_) != bool (now.grace_part_)) return; - Moment dur = unsmob_duration (m->get_property ("duration"))->get_length (); + Moment dur = unsmob_duration (ev->get_property ("duration"))->get_length (); consider_end (dur); consider_begin (dur); @@ -390,7 +386,7 @@ Auto_beam_engraver::acknowledge_stem (Grob_info info) durlog - 2); stems_->push_back (stem); last_add_mom_ = now; - extend_mom_ = max (extend_mom_, now) + m->get_length (); + extend_mom_ = max (extend_mom_, now) + get_event_length (ev); } void diff --git a/lily/beam-engraver.cc b/lily/beam-engraver.cc index f20160518e..fbd212efa1 100644 --- a/lily/beam-engraver.cc +++ b/lily/beam-engraver.cc @@ -16,6 +16,7 @@ #include "item.hh" #include "rest.hh" #include "spanner.hh" +#include "stream-event.hh" #include "stem.hh" #include "warn.hh" @@ -27,13 +28,13 @@ public: DECLARE_ACKNOWLEDGER (stem); DECLARE_ACKNOWLEDGER (rest); protected: - Music *start_ev_; + Stream_event *start_ev_; Spanner *finished_beam_; Spanner *beam_; - Music *prev_start_ev_; + Stream_event *prev_start_ev_; - Music *now_stop_ev_; + Stream_event *now_stop_ev_; Beaming_pattern *beam_info_; Beaming_pattern *finished_beam_info_; @@ -55,12 +56,12 @@ protected: void start_translation_timestep (); virtual void finalize (); - virtual bool try_music (Music *); void process_music (); virtual bool valid_start_point (); virtual bool valid_end_point (); + DECLARE_TRANSLATOR_LISTENER (beam); public: TRANSLATOR_DECLARATIONS (Beam_engraver); }; @@ -94,24 +95,16 @@ Beam_engraver::Beam_engraver () prev_start_ev_ = 0; } -bool -Beam_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Beam_engraver, beam); +void +Beam_engraver::listen_beam (Stream_event *ev) { - if (m->is_mus_type ("beam-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); - if (d == START && !valid_start_point ()) - return false; - if (d == STOP && !valid_end_point ()) - return false; - - if (d == START) - start_ev_ = m; - else if (d == STOP) - now_stop_ev_ = m; - return true; - } - return false; + Direction d = to_dir (ev->get_property ("span-direction")); + + if (d == START && valid_start_point ()) + start_ev_ = ev; + else if (d == STOP && valid_end_point ()) + now_stop_ev_ = ev; } void @@ -238,23 +231,18 @@ Beam_engraver::acknowledge_stem (Grob_info info) - Music *m = info.ultimate_music_cause (); - if (!m->is_mus_type ("rhythmic-event")) + Stream_event *ev = info.ultimate_event_cause (); + if (!ev->in_event_class ("rhythmic-event")) { - string s = _ ("stem must have Rhythmic structure"); - if (info.music_cause ()) - info.music_cause ()->origin ()->warning (s); - else - ::warning (s); - + info.grob ()->warning (_ ("stem must have Rhythmic structure")); return; } last_stem_added_at_ = now; - int durlog = unsmob_duration (m->get_property ("duration"))->duration_log (); + int durlog = unsmob_duration (ev->get_property ("duration"))->duration_log (); if (durlog <= 2) { - m->origin ()->warning (_ ("stem doesn't fit in beam")); + ev->origin ()->warning (_ ("stem doesn't fit in beam")); prev_start_ev_->origin ()->warning (_ ("beam was started here")); /* don't return, since diff --git a/lily/breathing-sign-engraver.cc b/lily/breathing-sign-engraver.cc index d7a73bf6be..5b2ddaff47 100644 --- a/lily/breathing-sign-engraver.cc +++ b/lily/breathing-sign-engraver.cc @@ -15,6 +15,9 @@ #include "breathing-sign.hh" #include "engraver.hh" #include "item.hh" +#include "stream-event.hh" + +#include "translator.icc" class Breathing_sign_engraver : public Engraver { @@ -22,12 +25,12 @@ public: TRANSLATOR_DECLARATIONS (Breathing_sign_engraver); protected: - virtual bool try_music (Music *event); void process_music (); void stop_translation_timestep (); + DECLARE_TRANSLATOR_LISTENER (breathing); private: - Music *breathing_sign_event_; + Stream_event *breathing_sign_event_; Grob *breathing_sign_; }; @@ -37,11 +40,11 @@ Breathing_sign_engraver::Breathing_sign_engraver () breathing_sign_event_ = 0; } -bool -Breathing_sign_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Breathing_sign_engraver, breathing); +void +Breathing_sign_engraver::listen_breathing (Stream_event *r) { breathing_sign_event_ = r; - return true; } void @@ -60,8 +63,6 @@ Breathing_sign_engraver::stop_translation_timestep () breathing_sign_event_ = 0; } -#include "translator.icc" - ADD_TRANSLATOR (Breathing_sign_engraver, /* doc */ "", /* create */ "BreathingSign", diff --git a/lily/chord-name-engraver.cc b/lily/chord-name-engraver.cc index 963c3033f2..20752ae2f7 100644 --- a/lily/chord-name-engraver.cc +++ b/lily/chord-name-engraver.cc @@ -6,17 +6,19 @@ (c) 1998--2006 Jan Nieuwenhuizen */ -#include "engraver.hh" #include "chord-name.hh" -#include "output-def.hh" -#include "font-interface.hh" -#include "output-def.hh" +#include "context.hh" #include "dimensions.hh" +#include "engraver.hh" +#include "font-interface.hh" #include "item.hh" +#include "output-def.hh" +#include "pitch.hh" #include "protected-scm.hh" -#include "context.hh" +#include "stream-event.hh" #include "warn.hh" -#include "pitch.hh" + +#include "translator.icc" class Chord_name_engraver : public Engraver { @@ -24,14 +26,12 @@ class Chord_name_engraver : public Engraver protected: void stop_translation_timestep (); void process_music (); - virtual bool try_music (Music *); virtual void finalize (); virtual void derived_mark () const; + DECLARE_TRANSLATOR_LISTENER (note); private: - void add_note (Music *); - Item *chord_name_; - vector notes_; + vector notes_; SCM last_chord_; }; @@ -53,12 +53,6 @@ Chord_name_engraver::Chord_name_engraver () last_chord_ = SCM_EOL; } -void -Chord_name_engraver::add_note (Music *n) -{ - notes_.push_back (n); -} - void Chord_name_engraver::process_music () { @@ -69,10 +63,10 @@ Chord_name_engraver::process_music () SCM inversion = SCM_EOL; SCM pitches = SCM_EOL; - Music *inversion_event = 0; + Stream_event *inversion_event = 0; for (vsize i = 0; i < notes_.size (); i++) { - Music *n = notes_[i]; + Stream_event *n = notes_[i]; SCM p = n->get_property ("pitch"); if (!unsmob_pitch (p)) continue; @@ -125,18 +119,11 @@ Chord_name_engraver::process_music () last_chord_ = chord_as_scm; } -bool -Chord_name_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note); +void +Chord_name_engraver::listen_note (Stream_event *ev) { - /* - hmm. Should check? - */ - if (m->is_mus_type ("note-event")) - { - add_note (m); - return true; - } - return false; + notes_.push_back (ev); } void @@ -150,8 +137,6 @@ Chord_name_engraver::stop_translation_timestep () The READs description is not strictly accurate: which properties are read depend on the chord naming function active. */ -#include "translator.icc" - ADD_TRANSLATOR (Chord_name_engraver, /* doc */ "Catch note-events " "and generate the appropriate chordname.", diff --git a/lily/chord-tremolo-engraver.cc b/lily/chord-tremolo-engraver.cc index 60800064c9..b0f17352ba 100644 --- a/lily/chord-tremolo-engraver.cc +++ b/lily/chord-tremolo-engraver.cc @@ -7,18 +7,18 @@ Erik Sandberg */ -#include "math.h" // ceil - #include "beam.hh" #include "engraver-group.hh" #include "international.hh" #include "item.hh" +#include "math.h" // ceil #include "misc.hh" #include "repeated-music.hh" #include "rhythmic-head.hh" #include "spanner.hh" #include "stem-tremolo.hh" #include "stem.hh" +#include "stream-event.hh" #include "warn.hh" #include "translator.icc" @@ -41,7 +41,7 @@ class Chord_tremolo_engraver : public Engraver { TRANSLATOR_DECLARATIONS (Chord_tremolo_engraver); protected: - Music *repeat_; + Stream_event *repeat_; int flags_; // number of beams for short tremolos @@ -52,8 +52,8 @@ protected: Spanner *beam_; protected: virtual void finalize (); - virtual bool try_music (Music *); void process_music (); + DECLARE_TRANSLATOR_LISTENER (tremolo_span); DECLARE_ACKNOWLEDGER (stem); }; @@ -66,31 +66,27 @@ Chord_tremolo_engraver::Chord_tremolo_engraver () beam_dir_ = CENTER; } -bool -Chord_tremolo_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Chord_tremolo_engraver, tremolo_span); +void +Chord_tremolo_engraver::listen_tremolo_span (Stream_event *ev) { - if (m->is_mus_type ("tremolo-span-event")) + Direction span_dir = to_dir (ev->get_property ("span-direction")); + if (span_dir == START) { - Direction span_dir = to_dir (m->get_property ("span-direction")); - if (span_dir == START) - { - repeat_ = m; - int type = scm_to_int (m->get_property ("tremolo-type")); - /* e.g. 1 for type 8, 2 for type 16 */ - flags_ = intlog2 (type) - 2; - expected_beam_count_ = scm_to_int (m->get_property ("expected-beam-count")); - beam_dir_ = RIGHT; - } - if (span_dir == STOP) - { - repeat_ = 0; - beam_ = 0; - expected_beam_count_ = 0; - beam_dir_ = CENTER; - } - return true; + repeat_ = ev; + int type = scm_to_int (ev->get_property ("tremolo-type")); + /* e.g. 1 for type 8, 2 for type 16 */ + flags_ = intlog2 (type) - 2; + expected_beam_count_ = scm_to_int (ev->get_property ("expected-beam-count")); + beam_dir_ = RIGHT; + } + else if (span_dir == STOP) + { + repeat_ = 0; + beam_ = 0; + expected_beam_count_ = 0; + beam_dir_ = CENTER; } - return false; } void diff --git a/lily/cluster-engraver.cc b/lily/cluster-engraver.cc index df26f6a689..33ee746e6b 100644 --- a/lily/cluster-engraver.cc +++ b/lily/cluster-engraver.cc @@ -12,19 +12,22 @@ #include "note-column.hh" #include "pointer-group-interface.hh" #include "pitch.hh" +#include "stream-event.hh" + +#include "translator.icc" class Cluster_spanner_engraver : public Engraver { protected: TRANSLATOR_DECLARATIONS (Cluster_spanner_engraver); - virtual bool try_music (Music *); - void process_music (); + DECLARE_TRANSLATOR_LISTENER (cluster_note); DECLARE_ACKNOWLEDGER (note_column); void stop_translation_timestep (); + virtual void process_music (); virtual void finalize (); private: - vector cluster_notes_; + vector cluster_notes_; Item *beacon_; void typeset_grobs (); @@ -55,18 +58,11 @@ Cluster_spanner_engraver::typeset_grobs () beacon_ = 0; } -bool -Cluster_spanner_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Cluster_spanner_engraver, cluster_note); +void +Cluster_spanner_engraver::listen_cluster_note (Stream_event *ev) { - if (m->is_mus_type ("cluster-note-event")) - { - cluster_notes_.push_back (m); - return true; - } - else if (m->is_mus_type ("busy-playing-event")) - return cluster_notes_.size (); - - return false; + cluster_notes_.push_back (ev); } void @@ -123,8 +119,6 @@ Cluster_spanner_engraver::acknowledge_note_column (Grob_info info) } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Cluster_spanner_engraver, note_column); ADD_TRANSLATOR (Cluster_spanner_engraver, /* doc */ "Engraves a cluster using Spanner notation ", diff --git a/lily/completion-note-heads-engraver.cc b/lily/completion-note-heads-engraver.cc index aee5e181c2..3e5056619d 100644 --- a/lily/completion-note-heads-engraver.cc +++ b/lily/completion-note-heads-engraver.cc @@ -7,20 +7,23 @@ #include using namespace std; -#include "rhythmic-head.hh" -#include "output-def.hh" -#include "music.hh" -#include "dots.hh" #include "dot-column.hh" -#include "staff-symbol-referencer.hh" +#include "dots.hh" +#include "duration.hh" +#include "global-context.hh" #include "item.hh" +#include "music.hh" +#include "output-def.hh" +#include "pitch.hh" +#include "rhythmic-head.hh" #include "score-engraver.hh" -#include "warn.hh" #include "spanner.hh" +#include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "tie.hh" -#include "global-context.hh" -#include "duration.hh" -#include "pitch.hh" +#include "warn.hh" + +#include "translator.icc" /* TODO: make matching rest engraver. @@ -48,8 +51,8 @@ class Completion_heads_engraver : public Engraver vector ties_; vector dots_; - vector note_events_; - vector scratch_note_events_; + vector note_events_; + vector scratch_note_events_; Moment note_end_mom_; bool is_first_; @@ -65,9 +68,9 @@ public: protected: virtual void initialize (); void start_translation_timestep (); - virtual bool try_music (Music *event); void process_music (); void stop_translation_timestep (); + DECLARE_TRANSLATOR_LISTENER (note); }; void @@ -76,29 +79,24 @@ Completion_heads_engraver::initialize () is_first_ = false; } -bool -Completion_heads_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Completion_heads_engraver, note); +void +Completion_heads_engraver::listen_note (Stream_event *ev) { - if (m->is_mus_type ("note-event")) - { - note_events_.push_back (m); - - is_first_ = true; - Moment musiclen = m->get_length (); - Moment now = now_mom (); - - if (now_mom ().grace_part_) - { - musiclen.grace_part_ = musiclen.main_part_; - musiclen.main_part_ = Rational (0, 1); - } - note_end_mom_ = max (note_end_mom_, (now + musiclen)); - do_nothing_until_ = Rational (0, 0); + note_events_.push_back (ev); + + is_first_ = true; + Moment musiclen = get_event_length (ev); + Moment now = now_mom (); - return true; + if (now_mom ().grace_part_) + { + musiclen.grace_part_ = musiclen.main_part_; + musiclen.main_part_ = Rational (0, 1); } - return false; + note_end_mom_ = max (note_end_mom_, (now + musiclen)); + do_nothing_until_ = Rational (0, 0); } /* @@ -192,14 +190,14 @@ Completion_heads_engraver::process_music () if (!scratch_note_events_.size ()) for (vsize i = 0; i < note_events_.size (); i++) { - Music *m = note_events_[i]->clone (); + Stream_event *m = note_events_[i]->clone (); scratch_note_events_.push_back (m); } } for (vsize i = 0; left_to_do_ && i < note_events_.size (); i++) { - Music *event = note_events_[i]; + Stream_event *event = note_events_[i]; if (scratch_note_events_.size ()) { event = scratch_note_events_[i]; @@ -294,8 +292,6 @@ Completion_heads_engraver::Completion_heads_engraver () { } -#include "translator.icc" - ADD_TRANSLATOR (Completion_heads_engraver, /* doc */ "This engraver replaces " "@code{Note_heads_engraver}. It plays some trickery to " diff --git a/lily/dispatcher.cc b/lily/dispatcher.cc index 9ba5fc2fc7..b86d045bc1 100644 --- a/lily/dispatcher.cc +++ b/lily/dispatcher.cc @@ -76,8 +76,7 @@ Dispatcher::dispatch (SCM sev) SCM class_list = scm_call_1 (ly_lily_module_constant ("ly:make-event-class"), class_symbol); if (!scm_is_pair (class_list)) { - // TODO: Re-enable this warning when the translator cleanup is finished - //ev->origin ()->warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ())); + ev->origin ()->warning (_f ("Unknown event class %s", ly_symbol2string (class_symbol).c_str ())); return; } bool sent = false; diff --git a/lily/drum-note-engraver.cc b/lily/drum-note-engraver.cc index 7a0adbda6e..5adc23d7eb 100644 --- a/lily/drum-note-engraver.cc +++ b/lily/drum-note-engraver.cc @@ -7,30 +7,33 @@ #include using namespace std; -#include "rhythmic-head.hh" +#include "duration.hh" #include "engraver.hh" -#include "warn.hh" +#include "note-column.hh" +#include "rhythmic-head.hh" #include "side-position-interface.hh" #include "script-interface.hh" #include "stem.hh" -#include "note-column.hh" -#include "duration.hh" +#include "stream-event.hh" +#include "warn.hh" + +#include "translator.icc" class Drum_notes_engraver : public Engraver { vector notes_; vector dots_; vector scripts_; - vector events_; + vector events_; public: TRANSLATOR_DECLARATIONS (Drum_notes_engraver); protected: - virtual bool try_music (Music *ev); void process_music (); DECLARE_ACKNOWLEDGER (stem); DECLARE_ACKNOWLEDGER (note_column); + DECLARE_TRANSLATOR_LISTENER (note); void stop_translation_timestep (); }; @@ -38,16 +41,11 @@ Drum_notes_engraver::Drum_notes_engraver () { } -bool -Drum_notes_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Drum_notes_engraver, note); +void +Drum_notes_engraver::listen_note (Stream_event *ev) { - if (m->is_mus_type ("note-event")) - { - events_.push_back (m); - return true; - } - - return false; + events_.push_back (ev); } void @@ -59,7 +57,7 @@ Drum_notes_engraver::process_music () if (!tab) tab = get_property ("drumStyleTable"); - Music *ev = events_[i]; + Stream_event *ev = events_[i]; Item *note = make_item ("NoteHead", ev->self_scm ()); Duration dur = *unsmob_duration (ev->get_property ("duration")); @@ -151,8 +149,6 @@ Drum_notes_engraver::stop_translation_timestep () events_.clear (); } -#include "translator.icc" - ADD_ACKNOWLEDGER (Drum_notes_engraver, stem); ADD_ACKNOWLEDGER (Drum_notes_engraver, note_column); ADD_TRANSLATOR (Drum_notes_engraver, diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index ab242f653c..09a7e39305 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -21,6 +21,7 @@ #include "self-alignment-interface.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "warn.hh" #include "translator.icc" @@ -50,10 +51,10 @@ class Dynamic_engraver : public Engraver Spanner *finished_line_spanner_; Spanner *finished_cresc_; - Music *script_ev_; - Music *current_cresc_ev_; + Stream_event *script_ev_; + Stream_event *current_cresc_ev_; - Drul_array accepted_spanevents_drul_; + Drul_array accepted_spanevents_drul_; vector pending_columns_; vector pending_elements_; @@ -66,10 +67,11 @@ class Dynamic_engraver : public Engraver DECLARE_ACKNOWLEDGER (stem_tremolo); DECLARE_ACKNOWLEDGER (note_column); DECLARE_ACKNOWLEDGER (slur); + DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); + DECLARE_TRANSLATOR_LISTENER (span_dynamic); protected: virtual void finalize (); - virtual bool try_music (Music *event); void stop_translation_timestep (); void process_music (); }; @@ -88,28 +90,25 @@ Dynamic_engraver::Dynamic_engraver () accepted_spanevents_drul_[STOP] = 0; } -bool -Dynamic_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, absolute_dynamic); +void +Dynamic_engraver::listen_absolute_dynamic (Stream_event *ev) { - if (m->is_mus_type ("absolute-dynamic-event")) - { - /* - TODO: probably broken. - */ - script_ev_ = m; - return true; - } - else if (m->is_mus_type ("decrescendo-event") - || m->is_mus_type ("crescendo-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); + /* + TODO: probably broken. + */ + script_ev_ = ev; +} - accepted_spanevents_drul_[d] = m; - if (current_cresc_ev_ && d == START) - accepted_spanevents_drul_[STOP] = m; - return true; - } - return false; +IMPLEMENT_TRANSLATOR_LISTENER (Dynamic_engraver, span_dynamic); +void +Dynamic_engraver::listen_span_dynamic (Stream_event *ev) +{ + Direction d = to_dir (ev->get_property ("span-direction")); + + accepted_spanevents_drul_[d] = ev; + if (current_cresc_ev_ && d == START) + accepted_spanevents_drul_[STOP] = ev; } void @@ -119,7 +118,7 @@ Dynamic_engraver::process_music () { if (!line_spanner_) { - Music *rq = accepted_spanevents_drul_[START]; + Stream_event *rq = accepted_spanevents_drul_[START]; line_spanner_ = make_spanner ("DynamicLineSpanner", rq ? rq->self_scm () : SCM_EOL); if (script_ev_) rq = script_ev_; @@ -153,7 +152,7 @@ Dynamic_engraver::process_music () Axis_group_interface::add_element (line_spanner_, script_); } - Music *stop_ev = accepted_spanevents_drul_ [STOP] + Stream_event *stop_ev = accepted_spanevents_drul_ [STOP] ? accepted_spanevents_drul_[STOP] : script_ev_; if (accepted_spanevents_drul_[STOP] || script_ev_) @@ -189,7 +188,7 @@ Dynamic_engraver::process_music () if (current_cresc_ev_) { string msg = _ ("already have a decrescendo"); - if (current_cresc_ev_->is_mus_type ("decrescendo-event")) + if (current_cresc_ev_->in_event_class ("crescendo-event")) msg = _ ("already have a crescendo"); accepted_spanevents_drul_[START]->origin ()->warning (msg); @@ -205,16 +204,19 @@ Dynamic_engraver::process_music () /* TODO: Use symbols. */ - - string start_type - = ly_symbol2string (current_cresc_ev_->get_property ("name")); - if (start_type == "DecrescendoEvent") + SCM start_sym = current_cresc_ev_->get_property ("class"); + string start_type; + + if (start_sym == ly_symbol2scm ("decrescendo-event")) start_type = "decrescendo"; - else if (start_type == "CrescendoEvent") + else if (start_sym == ly_symbol2scm ("crescendo-event")) start_type = "crescendo"; - - + else + { + programming_error ("unknown dynamic spanner type"); + return; + } /* UGH. TODO: should read from original event, so appearance diff --git a/lily/extender-engraver.cc b/lily/extender-engraver.cc index d3b2e90972..53938b24f6 100644 --- a/lily/extender-engraver.cc +++ b/lily/extender-engraver.cc @@ -15,13 +15,16 @@ #include "lyric-extender.hh" #include "note-head.hh" #include "pointer-group-interface.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + void completize_extender (Spanner *sp); class Extender_engraver : public Engraver { - Music *ev_; + Stream_event *ev_; Spanner *extender_; Spanner *pending_extender_; @@ -29,9 +32,9 @@ public: TRANSLATOR_DECLARATIONS (Extender_engraver); protected: + DECLARE_TRANSLATOR_LISTENER (extender); DECLARE_ACKNOWLEDGER (lyric_syllable); virtual void finalize (); - virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); }; @@ -43,15 +46,11 @@ Extender_engraver::Extender_engraver () ev_ = 0; } -bool -Extender_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Extender_engraver, extender); +void +Extender_engraver::listen_extender (Stream_event *ev) { - if (!ev_) - { - ev_ = r; - return true; - } - return false; + ASSIGN_EVENT_ONCE (ev_, ev); } void @@ -142,8 +141,6 @@ Extender_engraver::finalize () } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Extender_engraver, lyric_syllable); ADD_TRANSLATOR (Extender_engraver, /* doc */ "Create lyric extenders", diff --git a/lily/fall-engraver.cc b/lily/fall-engraver.cc index 2a865da024..2bc2e6ec13 100644 --- a/lily/fall-engraver.cc +++ b/lily/fall-engraver.cc @@ -9,6 +9,9 @@ #include "engraver.hh" #include "item.hh" #include "spanner.hh" +#include "stream-event.hh" + +#include "translator.icc" class Fall_engraver : public Engraver { @@ -17,7 +20,7 @@ public: DECLARE_ACKNOWLEDGER (note_head); protected: - virtual bool try_music (Music *event); + DECLARE_TRANSLATOR_LISTENER (bend_after); void process_music (); void stop_translation_timestep (); void start_translation_timestep (); @@ -25,7 +28,7 @@ protected: private: Moment stop_moment_; - Music *fall_event_; + Stream_event *fall_event_; Spanner *fall_; Grob *note_head_; }; @@ -76,7 +79,7 @@ Fall_engraver::acknowledge_note_head (Grob_info info) } note_head_ = info.grob (); - stop_moment_ = now_mom () + info.music_cause ()->get_length (); + stop_moment_ = now_mom () + get_event_length (info.event_cause ()); } Fall_engraver::Fall_engraver () @@ -86,11 +89,11 @@ Fall_engraver::Fall_engraver () fall_event_ = 0; } -bool -Fall_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Fall_engraver, bend_after); +void +Fall_engraver::listen_bend_after (Stream_event *ev) { - fall_event_ = r; - return true; + fall_event_ = ev; } void @@ -104,12 +107,8 @@ Fall_engraver::process_music () } } -#include "translator.icc" - - ADD_ACKNOWLEDGER (Fall_engraver, note_head); - ADD_TRANSLATOR (Fall_engraver, /* doc */ "Create fall spanners.", /* create */ "BendAfter", diff --git a/lily/figured-bass-engraver.cc b/lily/figured-bass-engraver.cc index 01b352f28d..9e0bf61786 100644 --- a/lily/figured-bass-engraver.cc +++ b/lily/figured-bass-engraver.cc @@ -9,16 +9,15 @@ #include "engraver.hh" +#include "align-interface.hh" +#include "axis-group-interface.hh" #include "context.hh" -#include "music.hh" +#include "grob-array.hh" #include "item.hh" -#include "spanner.hh" -#include "axis-group-interface.hh" -#include "align-interface.hh" #include "pointer-group-interface.hh" +#include "spanner.hh" +#include "stream-event.hh" #include "text-interface.hh" -#include "grob-array.hh" - #include "translator.icc" @@ -31,7 +30,7 @@ struct Figure_group SCM alteration_; Item *figure_item_; - Music *current_music_; + Stream_event *current_event_; bool force_no_continuation_; Figure_group () @@ -42,17 +41,17 @@ struct Figure_group number_ = SCM_EOL; alteration_ = SCM_EOL; group_ = 0; - current_music_ = 0; + current_event_ = 0; } bool is_continuation () const { return - current_music_ + current_event_ && !force_no_continuation_ && ly_is_equal (number_, - current_music_->get_property ("figure")) + current_event_->get_property ("figure")) && ly_is_equal (alteration_, - current_music_->get_property ("alteration")); + current_event_->get_property ("alteration")); } }; @@ -68,14 +67,16 @@ struct Figured_bass_engraver : public Engraver protected: vector groups_; Spanner *alignment_; - vector new_musics_; + vector new_events_; bool continuation_; - bool new_music_found_; + bool new_event_found_; Moment stop_moment_; - Music *rest_event_; - - virtual bool try_music (Music *); + Stream_event *rest_event_; + + DECLARE_TRANSLATOR_LISTENER (rest); + DECLARE_TRANSLATOR_LISTENER (bass_figure); + virtual void derived_mark () const; void start_translation_timestep (); @@ -103,7 +104,7 @@ Figured_bass_engraver::stop_translation_timestep () bool found = false; for (vsize i = 0; !found && i < groups_.size (); i++) - found = found || groups_[i].current_music_; + found = found || groups_[i].current_event_; if (!found) clear_spanners (); @@ -114,7 +115,7 @@ Figured_bass_engraver::Figured_bass_engraver () alignment_ = 0; continuation_ = false; rest_event_ = 0; - new_music_found_ = false; + new_event_found_ = false; } void @@ -125,43 +126,42 @@ Figured_bass_engraver::start_translation_timestep () return ; rest_event_ = 0; - new_musics_.clear (); + new_events_.clear (); for (vsize i = 0; i < groups_.size (); i++) - groups_[i].current_music_ = 0; + groups_[i].current_event_ = 0; continuation_ = false; } -bool -Figured_bass_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, rest); +void +Figured_bass_engraver::listen_rest (Stream_event *ev) { - new_music_found_ = true; - if (m->is_mus_type ("rest-event")) - { - rest_event_ = m; - return true; - } - else - { - stop_moment_ = now_mom () + m->get_length (); + new_event_found_ = true; + rest_event_ = ev; +} + +IMPLEMENT_TRANSLATOR_LISTENER (Figured_bass_engraver, bass_figure); +void +Figured_bass_engraver::listen_bass_figure (Stream_event *ev) +{ + new_event_found_ = true; + stop_moment_ = now_mom () + get_event_length (ev); - SCM fig = m->get_property ("figure"); - for (vsize i = 0; i < groups_.size (); i++) + SCM fig = ev->get_property ("figure"); + for (vsize i = 0; i < groups_.size (); i++) + { + if (!groups_[i].current_event_ + && ly_is_equal (groups_[i].number_, fig)) { - if (!groups_[i].current_music_ - && ly_is_equal (groups_[i].number_, fig)) - { - groups_[i].current_music_ = m; - groups_[i].force_no_continuation_ - = to_boolean (m->get_property ("no-continuation")); - continuation_ = true; - return true; - } + groups_[i].current_event_ = ev; + groups_[i].force_no_continuation_ + = to_boolean (ev->get_property ("no-continuation")); + continuation_ = true; + return; } - - new_musics_.push_back (m); - - return true; } + + new_events_.push_back (ev); } void @@ -244,20 +244,20 @@ Figured_bass_engraver::add_brackets () bool inside = false; for (vsize i = 0; i < groups_.size (); i ++) { - if (!groups_[i].current_music_) + if (!groups_[i].current_event_) continue; - if (to_boolean (groups_[i].current_music_->get_property ("bracket-start"))) + if (to_boolean (groups_[i].current_event_->get_property ("bracket-start"))) inside = true; if (inside && groups_[i].figure_item_) encompass.push_back (groups_[i].figure_item_); - if (to_boolean (groups_[i].current_music_->get_property ("bracket-stop"))) + if (to_boolean (groups_[i].current_event_->get_property ("bracket-stop"))) { inside = false; - Item * brack = make_item ("BassFigureBracket", groups_[i].current_music_->self_scm ()); + Item * brack = make_item ("BassFigureBracket", groups_[i].current_event_->self_scm ()); for (vsize j = 0; j < encompass.size (); j++) { Pointer_group_interface::add_grob (brack, @@ -280,17 +280,17 @@ Figured_bass_engraver::process_music () } if (!continuation_ - && new_musics_.empty ()) + && new_events_.empty ()) { clear_spanners (); groups_.clear (); return; } - if (!new_music_found_) + if (!new_event_found_) return; - new_music_found_ = false; + new_event_found_ = false; /* Don't need to sync alignments, if we're not using extenders. @@ -308,10 +308,10 @@ Figured_bass_engraver::process_music () } vsize k = 0; - for (vsize i = 0; i < new_musics_.size (); i++) + for (vsize i = 0; i < new_events_.size (); i++) { while (k < groups_.size () - && groups_[k].current_music_) + && groups_[k].current_event_) k++; if (k >= groups_.size ()) @@ -320,7 +320,7 @@ Figured_bass_engraver::process_music () groups_.push_back (group); } - groups_[k].current_music_ = new_musics_[i]; + groups_[k].current_event_ = new_events_[i]; groups_[k].figure_item_ = 0; k++; } @@ -408,14 +408,14 @@ Figured_bass_engraver::create_grobs () { Figure_group &group = groups_[i]; - if (group.current_music_) + if (group.current_event_) { Item *item = make_item ("BassFigure", - group.current_music_->self_scm ()); + group.current_event_->self_scm ()); - SCM fig = group.current_music_->get_property ("figure"); + SCM fig = group.current_event_->get_property ("figure"); if (!group.group_) { group.group_ = make_spanner ("BassFigureLine", SCM_EOL); @@ -431,13 +431,13 @@ Figured_bass_engraver::create_grobs () } group.number_ = fig; - group.alteration_ = group.current_music_->get_property ("alteration"); + group.alteration_ = group.current_event_->get_property ("alteration"); - SCM text = group.current_music_->get_property ("text"); + SCM text = group.current_event_->get_property ("text"); if (!Text_interface::is_markup (text) && ly_is_procedure (proc)) { - text = scm_call_3 (proc, fig, group.current_music_->self_scm (), + text = scm_call_3 (proc, fig, group.current_event_->self_scm (), context ()->self_scm ()); } diff --git a/lily/fingering-engraver.cc b/lily/fingering-engraver.cc index a8c4fcf680..8d8e2bce3f 100644 --- a/lily/fingering-engraver.cc +++ b/lily/fingering-engraver.cc @@ -7,39 +7,38 @@ */ #include "engraver.hh" -#include "side-position-interface.hh" -#include "stem.hh" +#include "pitch.hh" #include "rhythmic-head.hh" #include "self-alignment-interface.hh" -#include "pitch.hh" +#include "side-position-interface.hh" +#include "stem.hh" +#include "stream-event.hh" + +#include "translator.icc" class Fingering_engraver : public Engraver { - vector events_; + vector events_; vector fingerings_; public: TRANSLATOR_DECLARATIONS (Fingering_engraver); protected: - virtual bool try_music (Music *m); void stop_translation_timestep (); void process_music (); + DECLARE_TRANSLATOR_LISTENER (fingering); DECLARE_ACKNOWLEDGER (rhythmic_head); DECLARE_ACKNOWLEDGER (stem); private: - void make_script (Direction, Music *, int); + void make_script (Direction, Stream_event *, int); }; -bool -Fingering_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Fingering_engraver, fingering); +void +Fingering_engraver::listen_fingering (Stream_event *ev) { - if (m->is_mus_type ("fingering-event")) - { - events_.push_back (m); - return true; - } - return false; + events_.push_back (ev); } void @@ -72,7 +71,7 @@ Fingering_engraver::process_music () } void -Fingering_engraver::make_script (Direction d, Music *r, int i) +Fingering_engraver::make_script (Direction d, Stream_event *r, int i) { Item *fingering = make_item ("Fingering", r->self_scm ()); @@ -132,8 +131,6 @@ Fingering_engraver::Fingering_engraver () { } -#include "translator.icc" - ADD_ACKNOWLEDGER (Fingering_engraver, rhythmic_head); ADD_ACKNOWLEDGER (Fingering_engraver, stem); ADD_TRANSLATOR (Fingering_engraver, diff --git a/lily/glissando-engraver.cc b/lily/glissando-engraver.cc index f5b0527bd1..6368e05a09 100644 --- a/lily/glissando-engraver.cc +++ b/lily/glissando-engraver.cc @@ -10,8 +10,11 @@ #include "international.hh" #include "rhythmic-head.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + /** Create line-spanner grobs for glissandi lines that connect note heads. @@ -22,16 +25,16 @@ public: TRANSLATOR_DECLARATIONS (Glissando_engraver); protected: + DECLARE_TRANSLATOR_LISTENER (glissando); DECLARE_ACKNOWLEDGER (rhythmic_head); virtual void finalize (); - virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); private: Spanner *line_; Spanner *last_line_; - Music *event_; + Stream_event *event_; }; Glissando_engraver::Glissando_engraver () @@ -40,15 +43,11 @@ Glissando_engraver::Glissando_engraver () event_ = 0; } -bool -Glissando_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Glissando_engraver, glissando); +void +Glissando_engraver::listen_glissando (Stream_event *ev) { - if (!event_) - { - event_ = m; - return true; - } - return false; + ASSIGN_EVENT_ONCE (event_, ev); } void @@ -101,8 +100,6 @@ Glissando_engraver::finalize () } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Glissando_engraver, rhythmic_head); ADD_TRANSLATOR (Glissando_engraver, /* doc */ "Engrave a glissandi", diff --git a/lily/gregorian-ligature-engraver.cc b/lily/gregorian-ligature-engraver.cc index 31263e9a12..6a99e3946e 100644 --- a/lily/gregorian-ligature-engraver.cc +++ b/lily/gregorian-ligature-engraver.cc @@ -14,6 +14,7 @@ #include "pitch.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "warn.hh" /* @@ -32,16 +33,10 @@ Gregorian_ligature_engraver::Gregorian_ligature_engraver () pes_or_flexa_req_ = 0; } -bool -Gregorian_ligature_engraver::try_music (Music *m) +void +Gregorian_ligature_engraver::listen_pes_or_flexa (Stream_event *ev) { - if (m->is_mus_type ("pes-or-flexa-event")) - { - pes_or_flexa_req_ = m; - return true; - } - else - return Ligature_engraver::try_music (m); + pes_or_flexa_req_ = ev; } void fix_prefix (char *name, int mask, @@ -204,9 +199,9 @@ provide_context_info (vector primitives) for (vsize i = 0; i < primitives.size (); i++) { Grob *primitive = primitives[i].grob (); - Music *music_cause = primitives[i].music_cause (); + Stream_event *event_cause = primitives[i].event_cause (); int context_info = 0; - int pitch = unsmob_pitch (music_cause->get_property ("pitch"))->steps (); + int pitch = unsmob_pitch (event_cause->get_property ("pitch"))->steps (); int prefix_set = scm_to_int (primitive->get_property ("prefix-set")); if (prefix_set & PES_OR_FLEXA) diff --git a/lily/horizontal-bracket-engraver.cc b/lily/horizontal-bracket-engraver.cc index 5c553374a3..cfcd882a8e 100644 --- a/lily/horizontal-bracket-engraver.cc +++ b/lily/horizontal-bracket-engraver.cc @@ -12,6 +12,7 @@ #include "note-column.hh" #include "pointer-group-interface.hh" #include "side-position-interface.hh" +#include "stream-event.hh" #include "translator.icc" @@ -20,14 +21,14 @@ class Horizontal_bracket_engraver : public Engraver public: TRANSLATOR_DECLARATIONS (Horizontal_bracket_engraver); vector bracket_stack_; - vector events_; + vector events_; vsize pop_count_; vsize push_count_; - virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); DECLARE_ACKNOWLEDGER (note_column); + DECLARE_TRANSLATOR_LISTENER (note_grouping); }; ADD_ACKNOWLEDGER (Horizontal_bracket_engraver, note_column); @@ -44,31 +45,26 @@ Horizontal_bracket_engraver::Horizontal_bracket_engraver () push_count_ = 0; } -bool -Horizontal_bracket_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Horizontal_bracket_engraver, note_grouping); +void +Horizontal_bracket_engraver::listen_note_grouping (Stream_event *ev) { - if (m->is_mus_type ("note-grouping-event")) + Direction d = to_dir (ev->get_property ("span-direction")); + + if (d == STOP) { - Direction d = to_dir (m->get_property ("span-direction")); - - if (d == STOP) - { - pop_count_++; - if (pop_count_ > bracket_stack_.size ()) - m->origin ()->warning (_ ("don't have that many brackets")); - } - else - { - push_count_++; - events_.push_back (m); - } - - if (pop_count_ && push_count_) - m->origin ()->warning (_ ("conflicting note group events")); - - return true; + pop_count_++; + if (pop_count_ > bracket_stack_.size ()) + ev->origin ()->warning (_ ("don't have that many brackets")); } - return false; + else + { + push_count_++; + events_.push_back (ev); + } + + if (pop_count_ && push_count_) + ev->origin ()->warning (_ ("conflicting note group events")); } void diff --git a/lily/hyphen-engraver.cc b/lily/hyphen-engraver.cc index e4f4f3a991..989c8fb32c 100644 --- a/lily/hyphen-engraver.cc +++ b/lily/hyphen-engraver.cc @@ -13,12 +13,15 @@ #include "item.hh" #include "pointer-group-interface.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + class Hyphen_engraver : public Engraver { - Music *ev_; - Music *finished_ev_; + Stream_event *ev_; + Stream_event *finished_ev_; Spanner *hyphen_; Spanner *finished_hyphen_; @@ -29,9 +32,9 @@ public: protected: DECLARE_ACKNOWLEDGER (lyric_syllable); + DECLARE_TRANSLATOR_LISTENER (hyphen); virtual void finalize (); - virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); @@ -60,14 +63,11 @@ Hyphen_engraver::acknowledge_lyric_syllable (Grob_info i) finished_hyphen_->set_bound (RIGHT, item); } -bool -Hyphen_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Hyphen_engraver, hyphen); +void +Hyphen_engraver::listen_hyphen (Stream_event *ev) { - if (ev_) - return false; - - ev_ = r; - return true; + ASSIGN_EVENT_ONCE (ev_, ev); } void @@ -144,8 +144,6 @@ Hyphen_engraver::stop_translation_timestep () ev_ = 0; } -#include "translator.icc" - ADD_ACKNOWLEDGER (Hyphen_engraver, lyric_syllable); ADD_TRANSLATOR (Hyphen_engraver, diff --git a/lily/include/gregorian-ligature-engraver.hh b/lily/include/gregorian-ligature-engraver.hh index 96b87f84f2..1016993c4c 100644 --- a/lily/include/gregorian-ligature-engraver.hh +++ b/lily/include/gregorian-ligature-engraver.hh @@ -12,7 +12,7 @@ class Gregorian_ligature_engraver : public Coherent_ligature_engraver { - Music *pes_or_flexa_req_; + Stream_event *pes_or_flexa_req_; public: // no TRANSLATOR_DECLARATIONS (Gregorian_ligature_engraver) needed @@ -20,7 +20,8 @@ public: protected: Gregorian_ligature_engraver (); - virtual bool try_music (Music *); + + virtual void listen_pes_or_flexa (Stream_event *ev); virtual void build_ligature (Spanner *ligature, vector primitives); virtual void transform_heads (Spanner *ligature, vector primitives) = 0; diff --git a/lily/include/ligature-engraver.hh b/lily/include/ligature-engraver.hh index c70523ae91..2ae5cb4fe9 100644 --- a/lily/include/ligature-engraver.hh +++ b/lily/include/ligature-engraver.hh @@ -21,7 +21,7 @@ protected: DECLARE_ACKNOWLEDGER (rest); DECLARE_ACKNOWLEDGER (note_head); - virtual bool try_music (Music *); + virtual void listen_ligature (Stream_event *ev); void process_music (); virtual Spanner *create_ligature_spanner () = 0; virtual void typeset_ligature (Spanner *ligature, @@ -34,7 +34,7 @@ public: // class is abstract private: - Drul_array events_drul_; + Drul_array events_drul_; Spanner *ligature_; vector primitives_; @@ -42,7 +42,7 @@ private: Spanner *finished_ligature_; vector finished_primitives_; - Music *prev_start_event_; + Stream_event *prev_start_event_; // moment where ligature started. Moment ligature_start_mom_; diff --git a/lily/include/music.hh b/lily/include/music.hh index f09ba2f851..c307d07ff9 100644 --- a/lily/include/music.hh +++ b/lily/include/music.hh @@ -64,4 +64,7 @@ Music *make_music_by_name (SCM sym); SCM ly_music_deep_copy (SCM); extern SCM ly_music_p_proc; +/* common transposition function for music and event */ +SCM transpose_mutable (SCM alist, Pitch delta); + #endif /* MUSIC_HH */ diff --git a/lily/include/paper-column-engraver.hh b/lily/include/paper-column-engraver.hh index f850613bdd..d3b9430e35 100644 --- a/lily/include/paper-column-engraver.hh +++ b/lily/include/paper-column-engraver.hh @@ -10,6 +10,8 @@ #define PAPER_COLUMN_ENGRAVER_HH #include "engraver.hh" +#include "listener.hh" +#include "stream-event.hh" class Paper_column_engraver : public Engraver { @@ -23,14 +25,15 @@ protected: void process_music (); virtual void initialize (); virtual void finalize (); - virtual bool try_music (Music *); + + DECLARE_TRANSLATOR_LISTENER (break); DECLARE_ACKNOWLEDGER (item); DECLARE_ACKNOWLEDGER (note_spacing); DECLARE_ACKNOWLEDGER (staff_spacing); System *system_; - vector break_events_; + vector break_events_; int breaks_; // used for stat printing Paper_column *command_column_; Paper_column *musical_column_; diff --git a/lily/include/score-engraver.hh b/lily/include/score-engraver.hh index 47f7604f1a..d2de464f60 100644 --- a/lily/include/score-engraver.hh +++ b/lily/include/score-engraver.hh @@ -28,7 +28,6 @@ protected: /* Engraver_group_engraver interface */ virtual void connect_to_context (Context *); virtual void disconnect_from_context (); - virtual bool try_music (Music *); virtual void initialize (); virtual void finalize (); virtual void announce_grob (Grob_info); diff --git a/lily/include/stream-event.hh b/lily/include/stream-event.hh index 6a1f8d9845..991e672309 100644 --- a/lily/include/stream-event.hh +++ b/lily/include/stream-event.hh @@ -17,6 +17,13 @@ class Stream_event : public Prob { public: Stream_event (); + VIRTUAL_COPY_CONSTRUCTOR (Stream_event, Stream_event); + // todo: remove unneeded constructors + Stream_event (SCM event_class, SCM mutable_props); + Stream_event (SCM property_alist); + Stream_event (SCM class_name, Input *); + Stream_event (Stream_event *ev); + Input *origin () const; void set_spot (Input *i); bool internal_in_event_class (SCM class_name); @@ -24,11 +31,6 @@ public: DECLARE_SCHEME_CALLBACK (undump, (SCM)); DECLARE_SCHEME_CALLBACK (dump, (SCM)); - // todo: remove unneeded constructors - Stream_event (SCM event_class, SCM mutable_props); - Stream_event (SCM property_alist); - Stream_event (SCM class_name, Input *); - Stream_event (Stream_event *ev); }; #define in_event_class(class_name) internal_in_event_class (ly_symbol2scm (class_name)) diff --git a/lily/include/translator.icc b/lily/include/translator.icc index bff828bcad..904e3c127c 100644 --- a/lily/include/translator.icc +++ b/lily/include/translator.icc @@ -149,4 +149,10 @@ cl::_listen_scm_ ## m (SCM sev) \ listen_ ## m (ev); \ } +/* + This helper is only meaningful inside listen_* methods. +*/ +extern bool internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function); +#define ASSIGN_EVENT_ONCE(o,n) internal_event_assignment (&o, n, __FUNCTION__) + #endif /* TRANSLATOR_ICC */ diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc index b0a87988a4..f936283233 100644 --- a/lily/key-engraver.cc +++ b/lily/key-engraver.cc @@ -6,14 +6,15 @@ (c) 1997--2006 Han-Wen Nienhuys */ -#include "item.hh" #include "bar-line.hh" -#include "staff-symbol-referencer.hh" +#include "clef.hh" #include "context.hh" #include "engraver.hh" -#include "protected-scm.hh" -#include "clef.hh" +#include "item.hh" #include "pitch.hh" +#include "protected-scm.hh" +#include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "translator.icc" @@ -27,9 +28,9 @@ class Key_engraver : public Engraver { void create_key (bool); - void read_event (Music const *r); + void read_event (Stream_event const *r); - Music *key_event_; + Stream_event *key_event_; Item *item_; Item *cancellation_; public: @@ -38,10 +39,10 @@ public: protected: virtual void initialize (); virtual void finalize (); - virtual bool try_music (Music *event); void stop_translation_timestep (); void process_music (); + DECLARE_TRANSLATOR_LISTENER (key_change); DECLARE_ACKNOWLEDGER (clef); DECLARE_ACKNOWLEDGER (bar_line); }; @@ -111,20 +112,13 @@ Key_engraver::create_key (bool is_default) } } -bool -Key_engraver::try_music (Music *event) +IMPLEMENT_TRANSLATOR_LISTENER (Key_engraver, key_change); +void +Key_engraver::listen_key_change (Stream_event *ev) { - if (event->is_mus_type ("key-change-event")) - { - /* do this only once, just to be on the safe side. */ - if (!key_event_) - { - key_event_ = event; - read_event (key_event_); - } - return true; - } - return false; + /* do this only once, just to be on the safe side. */ + if (ASSIGN_EVENT_ONCE (key_event_, ev)) + read_event (key_event_); } void @@ -162,7 +156,7 @@ Key_engraver::stop_translation_timestep () } void -Key_engraver::read_event (Music const *r) +Key_engraver::read_event (Stream_event const *r) { SCM p = r->get_property ("pitch-alist"); if (!scm_is_pair (p)) diff --git a/lily/laissez-vibrer-engraver.cc b/lily/laissez-vibrer-engraver.cc index 4568dd19e4..cfc331da0c 100644 --- a/lily/laissez-vibrer-engraver.cc +++ b/lily/laissez-vibrer-engraver.cc @@ -11,20 +11,20 @@ #include "engraver.hh" #include "item.hh" #include "pointer-group-interface.hh" +#include "stream-event.hh" #include "translator.icc" class Laissez_vibrer_engraver : public Engraver { - - Music *event_; + Stream_event *event_; Grob *lv_column_; vector lv_ties_; void stop_translation_timestep (); DECLARE_ACKNOWLEDGER (note_head); - - virtual bool try_music (Music *); +protected: + DECLARE_TRANSLATOR_LISTENER (laissez_vibrer); public: TRANSLATOR_DECLARATIONS (Laissez_vibrer_engraver); }; @@ -43,11 +43,11 @@ Laissez_vibrer_engraver::stop_translation_timestep () lv_ties_.clear (); } -bool -Laissez_vibrer_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Laissez_vibrer_engraver, laissez_vibrer); +void +Laissez_vibrer_engraver::listen_laissez_vibrer (Stream_event *ev) { - event_ = m; - return true; + ASSIGN_EVENT_ONCE (event_, ev); } void @@ -71,8 +71,6 @@ Laissez_vibrer_engraver::acknowledge_note_head (Grob_info inf) lv_ties_.push_back (lv_tie); } - - ADD_ACKNOWLEDGER (Laissez_vibrer_engraver, note_head); ADD_TRANSLATOR (Laissez_vibrer_engraver, /* doc */ "Create Laissez vibrer items.", diff --git a/lily/ligature-engraver.cc b/lily/ligature-engraver.cc index 822df306ff..98e840b1ff 100644 --- a/lily/ligature-engraver.cc +++ b/lily/ligature-engraver.cc @@ -13,6 +13,7 @@ #include "note-head.hh" #include "rest.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" #include "translator.icc" @@ -77,16 +78,11 @@ Ligature_engraver::Ligature_engraver () brew_ligature_primitive_proc = SCM_EOL; } -bool -Ligature_engraver::try_music (Music *m) +void +Ligature_engraver::listen_ligature (Stream_event *ev) { - if (m->is_mus_type ("ligature-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); - events_drul_[d] = m; - return true; - } - return false; + Direction d = to_dir (ev->get_property ("span-direction")); + events_drul_[d] = ev; } void @@ -205,7 +201,7 @@ Ligature_engraver::acknowledge_rest (Grob_info info) { if (ligature_) { - info.music_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest")); + info.event_cause ()->origin ()->warning (_ ("ignoring rest: ligature may not contain rest")); prev_start_event_->origin ()->warning (_ ("ligature was started here")); // TODO: maybe better should stop ligature here rather than // ignoring the rest? diff --git a/lily/lyric-engraver.cc b/lily/lyric-engraver.cc index 176c9b7166..e11f4ec222 100644 --- a/lily/lyric-engraver.cc +++ b/lily/lyric-engraver.cc @@ -14,6 +14,9 @@ #include "multi-measure-rest.hh" #include "note-head.hh" #include "rest.hh" +#include "stream-event.hh" + +#include "translator.icc" /** Generate texts for lyric syllables. We only do one lyric at a time. @@ -23,14 +26,14 @@ class Lyric_engraver : public Engraver { protected: void stop_translation_timestep (); - virtual bool try_music (Music *); void process_music (); + DECLARE_TRANSLATOR_LISTENER (lyric); public: TRANSLATOR_DECLARATIONS (Lyric_engraver); private: - Music *event_; + Stream_event *event_; Item *text_; Item *last_text_; @@ -44,15 +47,11 @@ Lyric_engraver::Lyric_engraver () event_ = 0; } -bool -Lyric_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Lyric_engraver, lyric); +void +Lyric_engraver::listen_lyric (Stream_event *ev) { - if (!event_) - { - event_ = r; - return true; - } - return false; + ASSIGN_EVENT_ONCE (event_, ev); } void @@ -157,8 +156,6 @@ Lyric_engraver::stop_translation_timestep () event_ = 0; } -#include "translator.icc" - ADD_TRANSLATOR (Lyric_engraver, /* doc */ "", /* create */ "LyricText", diff --git a/lily/mark-engraver.cc b/lily/mark-engraver.cc index cb2ac141d9..b236779ac1 100644 --- a/lily/mark-engraver.cc +++ b/lily/mark-engraver.cc @@ -17,9 +17,12 @@ using namespace std; #include "grob-array.hh" #include "international.hh" #include "item.hh" +#include "stream-event.hh" #include "text-interface.hh" #include "warn.hh" +#include "translator.icc" + /** put stuff over or next to bars. Examples: bar numbers, marginal notes, rehearsal marks. @@ -27,18 +30,18 @@ using namespace std; class Mark_engraver : public Engraver { - void create_items (Music *); + void create_items (Stream_event *); Item *text_; - Music *mark_ev_; + Stream_event *mark_ev_; public: TRANSLATOR_DECLARATIONS (Mark_engraver); protected: - virtual bool try_music (Music *ev); void process_music (); void stop_translation_timestep (); + DECLARE_TRANSLATOR_LISTENER (mark); DECLARE_ACKNOWLEDGER (break_alignment); DECLARE_ACKNOWLEDGER (break_aligned); }; @@ -98,7 +101,7 @@ Mark_engraver::stop_translation_timestep () } void -Mark_engraver::create_items (Music *ev) +Mark_engraver::create_items (Stream_event *ev) { if (text_) return; @@ -106,11 +109,11 @@ Mark_engraver::create_items (Music *ev) text_ = make_item ("RehearsalMark", ev->self_scm ()); } -bool -Mark_engraver::try_music (Music *r) +IMPLEMENT_TRANSLATOR_LISTENER (Mark_engraver, mark); +void +Mark_engraver::listen_mark (Stream_event *ev) { - mark_ev_ = r; - return true; + mark_ev_ = ev; } /* @@ -158,8 +161,6 @@ Mark_engraver::process_music () } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Mark_engraver, break_aligned); ADD_ACKNOWLEDGER (Mark_engraver, break_alignment); diff --git a/lily/melisma-translator.cc b/lily/melisma-translator.cc index 74b0e10d5e..950eee3e05 100644 --- a/lily/melisma-translator.cc +++ b/lily/melisma-translator.cc @@ -11,6 +11,8 @@ #include "context.hh" #include "translator.icc" +/* Remove this translator. */ + /** Signal existence of melismas. */ @@ -67,6 +69,6 @@ Melisma_translator::Melisma_translator () ADD_TRANSLATOR (Melisma_translator, /* doc */ "This translator collects melisma information about ties, beams, and user settings (@code{melismaBusy}, and signals it to the @code{\addlyrics} code. ", /* create */ "", - /* accept */ "melisma-playing-event melisma-span-event", + /* accept */ "", /* read */ "melismaBusy melismaBusyProperties slurMelismaBusy tieMelismaBusy beamMelismaBusy", /* write */ ""); diff --git a/lily/mensural-ligature-engraver.cc b/lily/mensural-ligature-engraver.cc index 5adc44122c..c1c5bcad6d 100644 --- a/lily/mensural-ligature-engraver.cc +++ b/lily/mensural-ligature-engraver.cc @@ -19,8 +19,11 @@ #include "rhythmic-head.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + /* * TODO: accidentals are aligned with the first note; * they must appear ahead. @@ -47,7 +50,8 @@ class Mensural_ligature_engraver : public Coherent_ligature_engraver protected: virtual Spanner *create_ligature_spanner (); virtual void build_ligature (Spanner *ligature, vector primitives); - + DECLARE_TRANSLATOR_LISTENER (ligature); + public: TRANSLATOR_DECLARATIONS (Mensural_ligature_engraver); @@ -57,6 +61,13 @@ private: void fold_up_primitives (vector primitives); }; +IMPLEMENT_TRANSLATOR_LISTENER (Mensural_ligature_engraver, ligature); +void +Mensural_ligature_engraver::listen_ligature (Stream_event *ev) +{ + Ligature_engraver::listen_ligature (ev); +} + Mensural_ligature_engraver::Mensural_ligature_engraver () { brew_ligature_primitive_proc = @@ -382,8 +393,6 @@ Mensural_ligature_engraver::build_ligature (Spanner *ligature, fold_up_primitives (primitives); } -#include "translator.icc" - ADD_ACKNOWLEDGER (Mensural_ligature_engraver, rest); ADD_ACKNOWLEDGER (Mensural_ligature_engraver, note_head); ADD_TRANSLATOR (Mensural_ligature_engraver, diff --git a/lily/multi-measure-rest-engraver.cc b/lily/multi-measure-rest-engraver.cc index 3c7eed7524..ff073601e9 100644 --- a/lily/multi-measure-rest-engraver.cc +++ b/lily/multi-measure-rest-engraver.cc @@ -10,8 +10,11 @@ #include "engraver-group.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "moment.hh" +#include "translator.icc" + /** The name says it all: make multi measure rests */ @@ -21,15 +24,16 @@ public: TRANSLATOR_DECLARATIONS (Multi_measure_rest_engraver); protected: - virtual bool try_music (Music *); void process_music (); void stop_translation_timestep (); void start_translation_timestep (); virtual void finalize (); + DECLARE_TRANSLATOR_LISTENER (multi_measure_rest); + DECLARE_TRANSLATOR_LISTENER (multi_measure_text); private: - Music *rest_ev_; - vector text_events_; + Stream_event *rest_ev_; + vector text_events_; int start_measure_; Rational last_main_moment_; Moment stop_moment_; @@ -57,22 +61,19 @@ Multi_measure_rest_engraver::Multi_measure_rest_engraver () rest_ev_ = 0; } -bool -Multi_measure_rest_engraver::try_music (Music *event) +IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_rest); +void +Multi_measure_rest_engraver::listen_multi_measure_rest (Stream_event *ev) { - if (event->is_mus_type ("multi-measure-rest-event")) - { - rest_ev_ = event; - stop_moment_ = now_mom () + rest_ev_->get_length (); + rest_ev_ = ev; + stop_moment_ = now_mom () + get_event_length (rest_ev_); +} - return true; - } - else if (event->is_mus_type ("multi-measure-text-event")) - { - text_events_.push_back (event); - return true; - } - return false; +IMPLEMENT_TRANSLATOR_LISTENER (Multi_measure_rest_engraver, multi_measure_text); +void +Multi_measure_rest_engraver::listen_multi_measure_text (Stream_event *ev) +{ + text_events_.push_back (ev); } void @@ -91,8 +92,7 @@ Multi_measure_rest_engraver::process_music () { for (vsize i = 0; i < text_events_.size (); i++) { - - Music *e = text_events_[i]; + Stream_event *e = text_events_[i]; Spanner *sp = make_spanner ("MultiMeasureRestText", e->self_scm ()); SCM t = e->get_property ("text"); @@ -242,8 +242,6 @@ Multi_measure_rest_engraver::finalize () { } -#include "translator.icc" - ADD_TRANSLATOR (Multi_measure_rest_engraver, /* doc */ "Engraves multi-measure rests that are produced with @code{R}. Reads " diff --git a/lily/music.cc b/lily/music.cc index 246074f475..3775512538 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -184,15 +184,18 @@ Music::compress (Moment factor) set_property ("duration", d->compressed (factor.main_part_).smobbed_copy ()); } -void -Music::transpose (Pitch delta) +/* +TODO: make transposition non-destructive +*/ +SCM +transpose_mutable (SCM alist, Pitch delta) { - if (to_boolean (get_property ("untransposable"))) - return; + SCM retval = SCM_EOL; - for (SCM s = this->get_property_alist (true); scm_is_pair (s); s = scm_cdr (s)) + for (SCM s = alist; scm_is_pair (s); s = scm_cdr (s)) { SCM entry = scm_car (s); + SCM prop = scm_car (entry); SCM val = scm_cdr (entry); if (Pitch *p = unsmob_pitch (val)) @@ -206,21 +209,29 @@ Music::transpose (Pitch delta) delta.to_string ())); } } + else if (prop == ly_symbol2scm ("element")) + { + if (Music *m = unsmob_music (val)) + m->transpose (delta); + } + else if (prop == ly_symbol2scm ("elements")) + transpose_music_list (val, delta); + else if (prop == ly_symbol2scm ("pitch-alist") && + scm_is_pair (val)) + entry = scm_cons (prop, ly_transpose_key_alist (val, delta.smobbed_copy ())); + retval = scm_cons (entry, retval); } - SCM elt = get_property ("element"); - - if (Music *m = unsmob_music (elt)) - m->transpose (delta); + return scm_reverse_x (retval, SCM_EOL); +} - transpose_music_list (get_property ("elements"), delta); +void +Music::transpose (Pitch delta) +{ + if (to_boolean (get_property ("untransposable"))) + return; - /* - UGH - how do this more generically? - */ - SCM pa = get_property ("pitch-alist"); - if (scm_is_pair (pa)) - set_property ("pitch-alist", ly_transpose_key_alist (pa, delta.smobbed_copy ())); + mutable_property_alist_ = transpose_mutable (mutable_property_alist_, delta); } void @@ -258,6 +269,9 @@ Music::to_event () const out[outpos] = 0; SCM class_name = ly_symbol2scm (out); + // catch mistakes. + assert (internal_is_music_type (class_name)); + Stream_event *e = new Stream_event (class_name, mutable_property_alist_); Moment length = get_length (); if (length.to_bool ()) diff --git a/lily/note-heads-engraver.cc b/lily/note-heads-engraver.cc index d650b675e7..93fb8feb4d 100644 --- a/lily/note-heads-engraver.cc +++ b/lily/note-heads-engraver.cc @@ -9,26 +9,29 @@ #include using namespace std; -#include "rhythmic-head.hh" -#include "output-def.hh" #include "dots.hh" #include "dot-column.hh" -#include "staff-symbol-referencer.hh" +#include "duration.hh" #include "item.hh" +#include "output-def.hh" +#include "rhythmic-head.hh" +#include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "warn.hh" -#include "duration.hh" + +#include "translator.icc" class Note_heads_engraver : public Engraver { vector notes_; vector dots_; - vector note_evs_; + vector note_evs_; public: TRANSLATOR_DECLARATIONS (Note_heads_engraver); protected: - virtual bool try_music (Music *ev); + DECLARE_TRANSLATOR_LISTENER (note); void process_music (); void stop_translation_timestep (); }; @@ -37,16 +40,11 @@ Note_heads_engraver::Note_heads_engraver () { } -bool -Note_heads_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Note_heads_engraver, note); +void +Note_heads_engraver::listen_note (Stream_event *ev) { - if (m->is_mus_type ("note-event")) - { - note_evs_.push_back (m); - return true; - } - - return false; + note_evs_.push_back (ev); } void @@ -54,7 +52,7 @@ Note_heads_engraver::process_music () { for (vsize i = 0; i < note_evs_.size (); i++) { - Music *ev = note_evs_[i]; + Stream_event *ev = note_evs_[i]; Item *note = make_item ("NoteHead", ev->self_scm ()); Duration dur = *unsmob_duration (ev->get_property ("duration")); @@ -122,8 +120,6 @@ Note_heads_engraver::stop_translation_timestep () note_evs_.clear (); } -#include "translator.icc" - ADD_TRANSLATOR (Note_heads_engraver, /* doc */ "Generate noteheads.", /* create */ diff --git a/lily/note-name-engraver.cc b/lily/note-name-engraver.cc index 585eb1fae2..1222654dab 100644 --- a/lily/note-name-engraver.cc +++ b/lily/note-name-engraver.cc @@ -8,28 +8,27 @@ #include "engraver.hh" #include "item.hh" +#include "stream-event.hh" + +#include "translator.icc" class Note_name_engraver : public Engraver { public: TRANSLATOR_DECLARATIONS (Note_name_engraver); - vector events_; + vector events_; vector texts_; - virtual bool try_music (Music *m); + DECLARE_TRANSLATOR_LISTENER (note); void process_music (); void stop_translation_timestep (); }; -bool -Note_name_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Note_name_engraver, note); +void +Note_name_engraver::listen_note (Stream_event *ev) { - if (m->is_mus_type ("note-event")) - { - events_.push_back (m); - return true; - } - return false; + events_.push_back (ev); } void @@ -66,8 +65,6 @@ Note_name_engraver::Note_name_engraver () { } -#include "translator.icc" - ADD_TRANSLATOR (Note_name_engraver, /* doc */ "", /* create */ "NoteName", diff --git a/lily/output-property-engraver.cc b/lily/output-property-engraver.cc index 7f59d44430..76a2b6cb3f 100644 --- a/lily/output-property-engraver.cc +++ b/lily/output-property-engraver.cc @@ -8,8 +8,9 @@ */ #include "engraver.hh" -#include "grob.hh" #include "context.hh" +#include "grob.hh" +#include "stream-event.hh" #include "translator.icc" @@ -18,30 +19,23 @@ class Output_property_engraver : public Engraver { TRANSLATOR_DECLARATIONS (Output_property_engraver); protected: - vector props_; - DECLARE_ACKNOWLEDGER (grob) + vector props_; + DECLARE_ACKNOWLEDGER (grob); + DECLARE_TRANSLATOR_LISTENER (layout_instruction); void stop_translation_timestep (); - virtual bool try_music (Music*); }; - -bool -Output_property_engraver::try_music (Music* m) +IMPLEMENT_TRANSLATOR_LISTENER (Output_property_engraver, layout_instruction); +void +Output_property_engraver::listen_layout_instruction (Stream_event *ev) { - if (m->is_mus_type ("layout-instruction")) - { - /* - UGH. Only swallow the output property event in the context - it was intended for. This is inelegant but not inefficient. - */ - if (context ()->is_alias (m->get_property ("context-type"))) - { - props_.push_back (m); - return true; - } - } - return false; + /* + UGH. Only swallow the output property event in the context + it was intended for. This is inelegant but not inefficient. + */ + if (context ()->is_alias (ev->get_property ("context-type"))) + props_.push_back (ev); } void @@ -49,7 +43,7 @@ Output_property_engraver::acknowledge_grob (Grob_info inf) { for (vsize i = props_.size (); i--;) { - Music *o = props_[i]; + Stream_event *o = props_[i]; Context *d = inf.context (); SCM proc = o->get_property ("procedure"); scm_call_3 (proc, @@ -79,7 +73,7 @@ ADD_TRANSLATOR (Output_property_engraver, "", /* accept */ - "layout-instruction", + "layout-instruction-event", /* read */ "", diff --git a/lily/paper-column-engraver.cc b/lily/paper-column-engraver.cc index b6f249e9af..d3602d732a 100644 --- a/lily/paper-column-engraver.cc +++ b/lily/paper-column-engraver.cc @@ -7,14 +7,14 @@ */ #include "paper-column-engraver.hh" -#include "system.hh" +#include "axis-group-interface.hh" +#include "context.hh" #include "item.hh" -#include "paper-column.hh" -#include "staff-spacing.hh" #include "note-spacing.hh" +#include "paper-column.hh" #include "pointer-group-interface.hh" -#include "context.hh" -#include "axis-group-interface.hh" +#include "staff-spacing.hh" +#include "system.hh" #include "warn.hh" #include "translator.icc" @@ -108,12 +108,11 @@ Paper_column_engraver::set_columns (Paper_column *new_command, system_->add_column (musical_column_); } -bool -Paper_column_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Paper_column_engraver, break); +void +Paper_column_engraver::listen_break (Stream_event *ev) { - break_events_.push_back (m); - - return true; + break_events_.push_back (ev); } void @@ -122,18 +121,17 @@ Paper_column_engraver::process_music () for (vsize i = 0; i < break_events_.size (); i++) { string prefix; - SCM name = break_events_[i]->get_property ("name"); - if (name == ly_symbol2scm ("LineBreakEvent")) - prefix = "line-break"; - else if (name == ly_symbol2scm ("PageBreakEvent")) - prefix = "page-break"; - else if (name == ly_symbol2scm ("PageTurnEvent")) - prefix = "page-turn"; + SCM name_sym = break_events_[i]->get_property ("class"); + string name = ly_scm2string (scm_symbol_to_string (name_sym)); + size_t end = name.rfind ("-event"); + if (end) + prefix = name.substr (0, end); else { programming_error ("Paper_column_engraver doesn't know about this break-event"); return; } + string perm_str = prefix + "-permission"; string pen_str = prefix + "-penalty"; diff --git a/lily/parser.yy b/lily/parser.yy index d0109edac5..1d54ba9760 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -1735,7 +1735,7 @@ gen_text_def: $$ = t->unprotect (); } | DIGIT { - Music *t = MY_MAKE_MUSIC ("FingerEvent"); + Music *t = MY_MAKE_MUSIC ("FingeringEvent"); t->set_property ("digit", scm_from_int ($1)); t->set_spot (@$); $$ = t->unprotect (); diff --git a/lily/part-combine-engraver.cc b/lily/part-combine-engraver.cc index 016b08598e..b6f091442e 100644 --- a/lily/part-combine-engraver.cc +++ b/lily/part-combine-engraver.cc @@ -9,11 +9,14 @@ */ #include "engraver.hh" -#include "text-interface.hh" +#include "multi-measure-rest.hh" #include "note-head.hh" -#include "stem.hh" #include "side-position-interface.hh" -#include "multi-measure-rest.hh" +#include "stem.hh" +#include "stream-event.hh" +#include "text-interface.hh" + +#include "translator.icc" class Part_combine_engraver : public Engraver { @@ -23,19 +26,19 @@ protected: DECLARE_ACKNOWLEDGER (note_head); DECLARE_ACKNOWLEDGER (stem); + DECLARE_TRANSLATOR_LISTENER (part_combine); void process_music (); void stop_translation_timestep (); - virtual bool try_music (Music *); private: Item *text_; - Music *event_; + Stream_event *event_; }; -bool -Part_combine_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Part_combine_engraver, part_combine); +void +Part_combine_engraver::listen_part_combine (Stream_event *ev) { - event_ = m; - return true; + event_ = ev; } Part_combine_engraver::Part_combine_engraver () @@ -50,13 +53,13 @@ Part_combine_engraver::process_music () if (event_ && to_boolean (get_property ("printPartCombineTexts"))) { - SCM what = event_->get_property ("part-combine-status"); + SCM what = event_->get_property ("class"); SCM text = SCM_EOL; - if (what == ly_symbol2scm ("solo1")) + if (what == ly_symbol2scm ("solo1-event")) text = get_property ("soloText"); - else if (what == ly_symbol2scm ("solo2")) + else if (what == ly_symbol2scm ("solo2-event")) text = get_property ("soloIIText"); - else if (what == ly_symbol2scm ("unisono")) + else if (what == ly_symbol2scm ("unisono-event")) text = get_property ("aDueText"); if (Text_interface::is_markup (text)) @@ -94,7 +97,6 @@ Part_combine_engraver::stop_translation_timestep () event_ = 0; } -#include "translator.icc" ADD_ACKNOWLEDGER (Part_combine_engraver, note_head); ADD_ACKNOWLEDGER (Part_combine_engraver, stem); ADD_TRANSLATOR (Part_combine_engraver, diff --git a/lily/percent-repeat-engraver.cc b/lily/percent-repeat-engraver.cc index 81d831aff8..a27eef826b 100644 --- a/lily/percent-repeat-engraver.cc +++ b/lily/percent-repeat-engraver.cc @@ -18,6 +18,7 @@ #include "repeated-music.hh" #include "side-position-interface.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" #include "translator.icc" @@ -34,7 +35,7 @@ public: TRANSLATOR_DECLARATIONS (Percent_repeat_engraver); protected: - Music *percent_event_; + Stream_event *percent_event_; /// moment (global time) where percent started. Moment stop_mom_; @@ -53,7 +54,7 @@ protected: protected: virtual void finalize (); - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (percent); void stop_translation_timestep (); void start_translation_timestep (); @@ -68,13 +69,13 @@ Percent_repeat_engraver::Percent_repeat_engraver () percent_event_ = 0; } -bool -Percent_repeat_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Percent_repeat_engraver, percent); +void +Percent_repeat_engraver::listen_percent (Stream_event *ev) { - if (m->is_mus_type ("percent-event") - && !percent_event_) + if (!percent_event_) { - Moment body_length = m->get_length (); + Moment body_length = get_event_length (ev); Moment meas_len (robust_scm2moment (get_property ("measureLength"), Moment (1))); @@ -93,14 +94,10 @@ Percent_repeat_engraver::try_music (Music *m) get_global_context ()->add_moment_to_process (start_mom_); } else - return false; - - percent_event_ = m; + return; - return true; + percent_event_ = ev; } - - return false; } void diff --git a/lily/phrasing-slur-engraver.cc b/lily/phrasing-slur-engraver.cc index b3b9abbe00..d9c6e3e039 100644 --- a/lily/phrasing-slur-engraver.cc +++ b/lily/phrasing-slur-engraver.cc @@ -14,8 +14,11 @@ #include "note-column.hh" #include "slur.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + /* It is possible that a slur starts and ends on the same note. At least, it is for phrasing slurs: a note can be both beginning and @@ -24,14 +27,12 @@ class Phrasing_slur_engraver : public Engraver { - Drul_array events_; - Music *running_slur_start_; + Drul_array events_; + Stream_event *running_slur_start_; vector slurs_; vector end_slurs_; protected: - virtual bool try_music (Music *); - void acknowledge_extra_object (Grob_info); DECLARE_ACKNOWLEDGER (accidental); DECLARE_ACKNOWLEDGER (dynamic_line_spanner); @@ -41,6 +42,7 @@ protected: DECLARE_ACKNOWLEDGER (slur); DECLARE_ACKNOWLEDGER (text_script); DECLARE_ACKNOWLEDGER (tie); + DECLARE_TRANSLATOR_LISTENER (phrasing_slur); void stop_translation_timestep (); virtual void finalize (); @@ -55,30 +57,18 @@ Phrasing_slur_engraver::Phrasing_slur_engraver () events_[START] = events_[STOP] = 0; } -bool -Phrasing_slur_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, phrasing_slur); +void +Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev) { - if (m->is_mus_type ("phrasing-slur-event")) - { - /* - Let's not start more than one slur per moment. - */ - Direction d = to_dir (m->get_property ("span-direction")); - if (d == START) - { - events_[START] = m; - return true; - } - else if (d == STOP) - { - if (slurs_.empty ()) - return false; - - events_[STOP] = m; - return true; - } - } - return false; + /* + Let's not start more than one slur per moment. + */ + Direction d = to_dir (ev->get_property ("span-direction")); + if (d == START) + events_[START] = ev; + else if (d == STOP && !slurs_.empty ()) + events_[STOP] = ev; } void @@ -157,7 +147,7 @@ Phrasing_slur_engraver::process_music () if (events_[START] && slurs_.empty ()) { - Music *ev = events_[START]; + Stream_event *ev = events_[START]; Grob *slur = make_spanner ("PhrasingSlur", events_[START]->self_scm ()); Direction updown = to_dir (ev->get_property ("direction")); @@ -175,8 +165,6 @@ Phrasing_slur_engraver::stop_translation_timestep () events_[START] = events_[STOP] = 0; } -#include "translator.icc" - ADD_ACKNOWLEDGER (Phrasing_slur_engraver, accidental); ADD_ACKNOWLEDGER (Phrasing_slur_engraver, dynamic_line_spanner); ADD_ACKNOWLEDGER (Phrasing_slur_engraver, fingering) diff --git a/lily/piano-pedal-engraver.cc b/lily/piano-pedal-engraver.cc index 2d380fb352..afdcb741bb 100644 --- a/lily/piano-pedal-engraver.cc +++ b/lily/piano-pedal-engraver.cc @@ -3,7 +3,8 @@ source file of the GNU LilyPond music typesetter - (c) 2000--2006 Jan Nieuwenhuizen + (c) 2000--2006 Jan Nieuwenhuizen , + Erik Sandberg Chris Jackson - extended to support bracketed pedals. @@ -19,20 +20,41 @@ #include "note-column.hh" #include "side-position-interface.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" +#include "string-convert.hh" #include "warn.hh" +#include "translator.icc" + /* Urgh. This engraver is too complex. rewrite. --hwn */ +/* Ugh: This declaration is duplicated in piano-pedal-performer */ +typedef enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES}; + +/* + Static precalculated data (symbols and strings) for the different + pedal types +*/ +struct Pedal_type_info +{ + string base_name_; + SCM event_class_sym_; + SCM style_sym_; + SCM strings_sym_; + const char *pedal_line_spanner_c_str_; + const char *pedal_c_str_; +}; + struct Pedal_info { - char const *name_; + const Pedal_type_info *type_; /* Event for currently running pedal. */ - Music *current_bracket_ev_; + Stream_event *current_bracket_ev_; /* Event for currently starting pedal, (necessary? @@ -40,12 +62,12 @@ struct Pedal_info distinct from current_bracket_ev_, since current_bracket_ev_ only necessary for brackets, not for text style. */ - Music *start_ev_; + Stream_event *start_ev_; /* Events that were found in this timestep. */ - Drul_array event_drul_; + Drul_array event_drul_; Item *item_; Spanner *bracket_; // A single portion of a pedal bracket Spanner *finished_bracket_; @@ -57,6 +79,8 @@ struct Pedal_info Spanner *finished_line_spanner_; }; +static Pedal_type_info pedal_types_[NUM_PEDAL_TYPES]; + class Piano_pedal_engraver : public Engraver { public: @@ -65,14 +89,15 @@ public: protected: virtual void initialize (); virtual void finalize (); - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (sustain); + DECLARE_TRANSLATOR_LISTENER (una_corda); + DECLARE_TRANSLATOR_LISTENER (sostenuto); void stop_translation_timestep (); DECLARE_ACKNOWLEDGER (note_column); void process_music (); private: - - Pedal_info *info_list_; + Pedal_info info_list_[NUM_PEDAL_TYPES + 1]; /* Record a stack of the current pedal spanners, so if more than one pedal @@ -87,41 +112,71 @@ private: void typeset_all (Pedal_info *p); }; +static void +init_pedal_types () +{ + const char *names [NUM_PEDAL_TYPES]; + names[SOSTENUTO] = "Sostenuto"; + names[SUSTAIN] = "Sustain"; + names[UNA_CORDA] = "UnaCorda"; + + for (int i = 0; i < NUM_PEDAL_TYPES; i++) + { + const char *name = names[i]; + /* FooBar */ + string base_name = name; + /* foo-bar */ + string base_ident = ""; + int prev_pos=0; + int cur_pos; + for (cur_pos = 1; name[cur_pos]; cur_pos++) + if (isupper (name[cur_pos])) + { + base_ident = base_ident + String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos)) + "-"; + prev_pos = cur_pos; + } + base_ident += String_convert::to_lower (string (name, prev_pos, cur_pos - prev_pos)); + + Pedal_type_info *tbl = &pedal_types_[i]; + tbl->base_name_ = name; + /* These symbols are static and need to be protected */ + tbl->event_class_sym_ = scm_gc_protect_object (scm_str2symbol ((base_ident + "-event").c_str ())); + tbl->pedal_line_spanner_c_str_ = strdup ((base_name + "PedalLineSpanner").c_str ()); + tbl->style_sym_ = scm_gc_protect_object (scm_str2symbol (("pedal" + base_name + "Style").c_str ())); + tbl->strings_sym_ = scm_gc_protect_object (scm_str2symbol (("pedal" + base_name + "Strings").c_str ())); + tbl->pedal_c_str_ = strdup ((base_name + "Pedal").c_str ()); + } +} +ADD_SCM_INIT_FUNC (Piano_pedal_engraver_init_pedal_types_, init_pedal_types); + Piano_pedal_engraver::Piano_pedal_engraver () { - info_list_ = 0; } void Piano_pedal_engraver::initialize () { - char *names [] = { "Sostenuto", "Sustain", "UnaCorda", 0 }; - - info_list_ = new Pedal_info[sizeof (names) / sizeof (char const *)]; - Pedal_info *p = info_list_; - - char **np = names; - do + for (int i = 0; i < NUM_PEDAL_TYPES; i++) { - p->name_ = *np; - p->item_ = 0; - p->bracket_ = 0; - p->finished_bracket_ = 0; - p->line_spanner_ = 0; - p->finished_line_spanner_ = 0; - p->current_bracket_ev_ = 0; - p->event_drul_[START] = 0; - p->event_drul_[STOP] = 0; - p->start_ev_ = 0; - - p++; + Pedal_type_info *s = &pedal_types_[i]; + Pedal_info *info = &info_list_[i]; + + info->type_ = s; + info->item_ = 0; + info->bracket_ = 0; + info->finished_bracket_ = 0; + info->line_spanner_ = 0; + info->finished_line_spanner_ = 0; + info->current_bracket_ev_ = 0; + info->event_drul_[START] = 0; + info->event_drul_[STOP] = 0; + info->start_ev_ = 0; } - while (* (np++)); + info_list_[NUM_PEDAL_TYPES].type_ = 0; } Piano_pedal_engraver::~Piano_pedal_engraver () { - delete[] info_list_; } /* @@ -131,7 +186,7 @@ Piano_pedal_engraver::~Piano_pedal_engraver () void Piano_pedal_engraver::acknowledge_note_column (Grob_info info) { - for (Pedal_info *p = info_list_; p && p->name_; p++) + for (Pedal_info *p = info_list_; p->type_; p++) { if (p->line_spanner_) { @@ -145,38 +200,42 @@ Piano_pedal_engraver::acknowledge_note_column (Grob_info info) } } -bool -Piano_pedal_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sostenuto); +void +Piano_pedal_engraver::listen_sostenuto (Stream_event *r) { - if (m->is_mus_type ("pedal-event")) - { - for (Pedal_info *p = info_list_; p->name_; p++) - { - string nm = p->name_ + string ("Event"); - if (ly_is_equal (m->get_property ("name"), - scm_str2symbol (nm.c_str ()))) - { - Direction d = to_dir (m->get_property ("span-direction")); - p->event_drul_[d] = m; - return true; - } - } - } - return false; + Direction d = to_dir (r->get_property ("span-direction")); + info_list_[SOSTENUTO].event_drul_[d] = r; +} + +IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, sustain); +void +Piano_pedal_engraver::listen_sustain (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + info_list_[SUSTAIN].event_drul_[d] = r; +} + +IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_engraver, una_corda); +void +Piano_pedal_engraver::listen_una_corda (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + info_list_[UNA_CORDA].event_drul_[d] = r; } void Piano_pedal_engraver::process_music () { - for (Pedal_info *p = info_list_; p && p->name_; p++) + for (Pedal_info *p = info_list_; p->type_; p++) { if (p->event_drul_[STOP] || p->event_drul_[START]) { if (!p->line_spanner_) { - string name = string (p->name_) + "PedalLineSpanner"; - Music *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]); - p->line_spanner_ = make_spanner (name.c_str (), rq->self_scm ()); + const char *name = p->type_->pedal_line_spanner_c_str_; + Stream_event *rq = (p->event_drul_[START] ? p->event_drul_[START] : p->event_drul_[STOP]); + p->line_spanner_ = make_spanner (name, rq->self_scm ()); } /* Choose the appropriate grobs to add to the line spanner @@ -192,8 +251,7 @@ Piano_pedal_engraver::process_music () mixed: Ped. _____/\____| */ - string prop = string ("pedal") + p->name_ + "Style"; - SCM style = get_property (prop.c_str ()); + SCM style = internal_get_property (p->type_->style_sym_); bool mixed = style == ly_symbol2scm ("mixed"); bool bracket = (mixed @@ -213,11 +271,11 @@ void Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) { SCM s = SCM_EOL; - SCM strings = get_property (("pedal" + string (p->name_) + "Strings").c_str ()); + SCM strings = internal_get_property (p->type_->strings_sym_); if (scm_ilength (strings) < 3) { - Music *m = p->event_drul_[START]; + Stream_event *m = p->event_drul_[START]; if (!m) m = p->event_drul_ [STOP]; string msg = _f ("expect 3 strings for piano pedals, found: %ld", @@ -235,7 +293,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) if (!mixed) { if (!p->start_ev_) - p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_)); + p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ())); else s = scm_cadr (strings); p->start_ev_ = p->event_drul_[START]; @@ -246,7 +304,7 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) if (!mixed) { if (!p->start_ev_) - p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->name_)); + p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", p->type_->base_name_.c_str ())); else s = scm_caddr (strings); p->start_ev_ = 0; @@ -271,11 +329,11 @@ Piano_pedal_engraver::create_text_grobs (Pedal_info *p, bool mixed) if (scm_is_string (s)) { - string propname = string (p->name_) + "Pedal"; + const char *propname = p->type_->pedal_c_str_; - p->item_ = make_item (propname.c_str (), (p->event_drul_[START] - ? p->event_drul_[START] - : p->event_drul_[STOP])->self_scm ()); + p->item_ = make_item (propname, (p->event_drul_[START] + ? p->event_drul_[START] + : p->event_drul_[STOP])->self_scm ()); p->item_->set_property ("text", s); Axis_group_interface::add_element (p->line_spanner_, p->item_); @@ -293,7 +351,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed) { if (!p->bracket_ && p->event_drul_[STOP]) { - string msg = _f ("can't find start of piano pedal bracket: `%s'", p->name_); + string msg = _f ("can't find start of piano pedal bracket: `%s'", p->type_->base_name_.c_str ()); p->event_drul_[STOP]->origin ()->warning (msg); p->event_drul_[STOP] = 0; } @@ -399,7 +457,7 @@ Piano_pedal_engraver::create_bracket_grobs (Pedal_info *p, bool mixed) void Piano_pedal_engraver::finalize () { - for (Pedal_info *p = info_list_; p && p->name_; p++) + for (Pedal_info *p = info_list_; p->type_; p++) { /* suicide? @@ -446,7 +504,7 @@ Piano_pedal_engraver::del_linespanner (Spanner *g) void Piano_pedal_engraver::stop_translation_timestep () { - for (Pedal_info *p = info_list_; p && p->name_; p++) + for (Pedal_info *p = info_list_; p->type_; p++) { if (!p->bracket_) { @@ -458,7 +516,7 @@ Piano_pedal_engraver::stop_translation_timestep () typeset_all (p); } - for (Pedal_info *p = info_list_; p->name_; p++) + for (Pedal_info *p = info_list_; p->type_; p++) { p->event_drul_[STOP] = 0; p->event_drul_[START] = 0; @@ -510,8 +568,6 @@ Piano_pedal_engraver::typeset_all (Pedal_info *p) } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Piano_pedal_engraver, note_column); ADD_TRANSLATOR (Piano_pedal_engraver, diff --git a/lily/piano-pedal-performer.cc b/lily/piano-pedal-performer.cc index 4048bb57a7..779624cdc4 100644 --- a/lily/piano-pedal-performer.cc +++ b/lily/piano-pedal-performer.cc @@ -15,10 +15,7 @@ #include "translator.icc" -#define SOSTENUTO 0 -#define SUSTAIN 1 -#define UNA_CORDA 2 -#define NUM_PEDAL_TYPES 3 +typedef enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES}; /** perform Piano pedals @@ -89,14 +86,15 @@ Piano_pedal_performer::process_music () for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++) { + string pedal_type = pedal_type_str (i); if (p->event_drul_[STOP]) { if (!p->start_event_) - p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", pedal_type_str (i))); + p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", pedal_type)); else { Audio_piano_pedal *a = new Audio_piano_pedal; - a->type_string_ = string (pedal_type_str (i)); + a->type_string_ = pedal_type; a->dir_ = STOP; audios_.push_back (a); Audio_element_info info(a, p->event_drul_[STOP]); @@ -109,7 +107,7 @@ Piano_pedal_performer::process_music () { p->start_event_ = p->event_drul_[START]; Audio_piano_pedal *a = new Audio_piano_pedal; - a->type_string_ = string (pedal_type_str (i)); + a->type_string_ = pedal_type; a->dir_ = START; audios_.push_back (a); Audio_element_info info(a, p->event_drul_[START]); diff --git a/lily/quote-iterator.cc b/lily/quote-iterator.cc index 9ca8fd25b7..dead1d503e 100644 --- a/lily/quote-iterator.cc +++ b/lily/quote-iterator.cc @@ -9,11 +9,13 @@ #include "music-wrapper-iterator.hh" #include "context.hh" +#include "dispatcher.hh" #include "input.hh" #include "international.hh" #include "lily-guile.hh" #include "music-sequence.hh" #include "music.hh" +#include "stream-event.hh" #include "warn.hh" class Quote_iterator : public Music_wrapper_iterator @@ -33,7 +35,7 @@ public: DECLARE_SCHEME_CALLBACK (constructor, ()); bool quote_ok () const; - bool accept_music_type (Music *) const; + bool accept_music_type (Stream_event *) const; protected: virtual void derived_mark () const; @@ -52,16 +54,14 @@ Quote_iterator::do_quit () } bool -Quote_iterator::accept_music_type (Music *mus) const +Quote_iterator::accept_music_type (Stream_event *ev) const { - SCM accept = get_outlet ()->get_property ("quotedEventTypes"); - for (SCM s = mus->get_property ("types"); - scm_is_pair (s); s = scm_cdr (s)) + for (SCM accept = get_outlet ()->get_property ("quotedEventTypes"); + scm_is_pair (accept); accept = scm_cdr (accept)) { - if (scm_memq (scm_car (s), accept) != SCM_BOOL_F) + if (ev->internal_in_event_class (scm_car (accept))) return true; } - return false; } @@ -230,11 +230,12 @@ Quote_iterator::process (Moment m) { SCM ev_acc = scm_car (s); - Music *mus = unsmob_music (scm_car (ev_acc)); - if (!mus) + Stream_event *ev = unsmob_stream_event (scm_car (ev_acc)); + if (!ev) programming_error ("no music found in quote"); - else if (accept_music_type (mus)) + else if (accept_music_type (ev)) { + /* create a transposed copy if necessary */ if (quote_pitch || me_pitch) { Pitch qp, mp; @@ -245,14 +246,11 @@ Quote_iterator::process (Moment m) Pitch diff = pitch_interval (qp, mp); - SCM copy = ly_music_deep_copy (mus->self_scm ()); - mus = unsmob_music (copy); - - transposed_musics_ = scm_cons (copy, transposed_musics_); - mus->transpose (diff); + SCM props = transpose_mutable (ev->get_property_alist (true), diff); + ev = new Stream_event (ev->get_property ("class"), props); + transposed_musics_ = scm_cons (ev->unprotect (), transposed_musics_); } - - quote_outlet_.get_outlet ()->try_music (mus); + quote_outlet_.get_outlet ()->event_source ()->broadcast (ev); } } diff --git a/lily/recording-group-engraver.cc b/lily/recording-group-engraver.cc index c0091cc834..e230316d8f 100644 --- a/lily/recording-group-engraver.cc +++ b/lily/recording-group-engraver.cc @@ -9,6 +9,9 @@ #include "recording-group-engraver.hh" #include "context.hh" +/* + TODO: Junk this class, extract events directly instead. +*/ void Recording_group_engraver::derived_mark () const { diff --git a/lily/repeat-tie-engraver.cc b/lily/repeat-tie-engraver.cc index 4bce211310..c9e8c9c208 100644 --- a/lily/repeat-tie-engraver.cc +++ b/lily/repeat-tie-engraver.cc @@ -11,19 +11,20 @@ #include "engraver.hh" #include "item.hh" #include "pointer-group-interface.hh" +#include "stream-event.hh" #include "translator.icc" class Repeat_tie_engraver : public Engraver { - Music *event_; + Stream_event *event_; Grob *semi_tie_column_; vector semi_ties_; void stop_translation_timestep (); DECLARE_ACKNOWLEDGER (note_head); + DECLARE_TRANSLATOR_LISTENER (repeat_tie); - virtual bool try_music (Music *); public: TRANSLATOR_DECLARATIONS (Repeat_tie_engraver); }; @@ -42,11 +43,11 @@ Repeat_tie_engraver::stop_translation_timestep () semi_ties_.clear (); } -bool -Repeat_tie_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Repeat_tie_engraver, repeat_tie); +void +Repeat_tie_engraver::listen_repeat_tie (Stream_event *ev) { - event_ = m; - return true; + event_ = ev; } void @@ -69,8 +70,6 @@ Repeat_tie_engraver::acknowledge_note_head (Grob_info inf) semi_ties_.push_back (semi_tie); } - - ADD_ACKNOWLEDGER (Repeat_tie_engraver, note_head); ADD_TRANSLATOR (Repeat_tie_engraver, /* doc */ "Create Laissez vibrer items.", diff --git a/lily/rest-engraver.cc b/lily/rest-engraver.cc index 7dffbeb9dd..b59acf73f4 100644 --- a/lily/rest-engraver.cc +++ b/lily/rest-engraver.cc @@ -8,23 +8,24 @@ #include "engraver.hh" +#include "dots.hh" #include "duration.hh" #include "item.hh" -#include "staff-symbol-referencer.hh" -#include "dots.hh" #include "rhythmic-head.hh" -#include "music.hh" +#include "staff-symbol-referencer.hh" +#include "stream-event.hh" + +#include "translator.icc" class Rest_engraver : public Engraver { - Music *rest_event_; + Stream_event *rest_event_; Item *dot_; Grob *rest_; protected: - virtual bool try_music (Music *); void start_translation_timestep (); void process_music (); - + DECLARE_TRANSLATOR_LISTENER (rest); public: TRANSLATOR_DECLARATIONS (Rest_engraver); }; @@ -88,19 +89,13 @@ Rest_engraver::process_music () } } -bool -Rest_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Rest_engraver, rest); +void +Rest_engraver::listen_rest (Stream_event *ev) { - if (m->is_mus_type ("rest-event")) - { - rest_event_ = m; - return true; - } - return false; + ASSIGN_EVENT_ONCE (rest_event_, ev); } -#include "translator.icc" - ADD_TRANSLATOR (Rest_engraver, /* doc */ "", /* create */ "Rest Dots", diff --git a/lily/score-engraver.cc b/lily/score-engraver.cc index 9ad0998cfb..09d1aa6a0f 100644 --- a/lily/score-engraver.cc +++ b/lily/score-engraver.cc @@ -157,15 +157,6 @@ Score_engraver::typeset_all () elems_.clear (); } -bool -Score_engraver::try_music (Music *m) -{ - if (Engraver_group::try_music (m)) - return true; - - return false; -} - ADD_TRANSLATOR_GROUP (Score_engraver, /* doc */ "Top level engraver. Takes care of generating columns and the complete system (ie. System) " "\n\n " diff --git a/lily/script-engraver.cc b/lily/script-engraver.cc index 9a06474c6b..7c05131a85 100644 --- a/lily/script-engraver.cc +++ b/lily/script-engraver.cc @@ -19,11 +19,14 @@ #include "slur.hh" #include "staff-symbol-referencer.hh" #include "stem.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + struct Script_tuple { - Music *event_; + Stream_event *event_; Grob *script_; Script_tuple () { @@ -38,10 +41,10 @@ class Script_engraver : public Engraver Spanner *slur_; protected: - virtual bool try_music (Music *); void stop_translation_timestep (); void process_music (); + DECLARE_TRANSLATOR_LISTENER (articulation); DECLARE_ACKNOWLEDGER (slur); DECLARE_ACKNOWLEDGER (rhythmic_head); DECLARE_ACKNOWLEDGER (stem); @@ -57,25 +60,21 @@ Script_engraver::Script_engraver () slur_ = 0; } -bool -Script_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Script_engraver, articulation); +void +Script_engraver::listen_articulation (Stream_event *ev) { - if (m->is_mus_type ("articulation-event")) - { - /* Discard double articulations for part-combining. */ - int script_count = scripts_.size (); - for (int i = 0; i < script_count; i++) - if (ly_is_equal (scripts_[i].event_ - ->get_property ("articulation-type"), - m->get_property ("articulation-type"))) - return true; - - Script_tuple t; - t.event_ = m; - scripts_.push_back (t); - return true; - } - return false; + /* Discard double articulations for part-combining. */ + int script_count = scripts_.size (); + for (int i = 0; i < script_count; i++) + if (ly_is_equal (scripts_[i].event_ + ->get_property ("articulation-type"), + ev->get_property ("articulation-type"))) + return; + + Script_tuple t; + t.event_ = ev; + scripts_.push_back (t); } void @@ -153,17 +152,17 @@ Script_engraver::process_music () { for (vsize i = 0; i < scripts_.size (); i++) { - Music *music = scripts_[i].event_; + Stream_event *ev = scripts_[i].event_; - Grob *p = make_item ("Script", music->self_scm ()); + Grob *p = make_item ("Script", ev->self_scm ()); make_script_from_event (p, context (), - music->get_property ("articulation-type"), + ev->get_property ("articulation-type"), i); scripts_[i].script_ = p; - SCM force_dir = music->get_property ("direction"); + SCM force_dir = ev->get_property ("direction"); if (is_direction (force_dir) && to_dir (force_dir)) p->set_property ("direction", force_dir); } @@ -199,7 +198,7 @@ Script_engraver::acknowledge_stem_tremolo (Grob_info info) void Script_engraver::acknowledge_rhythmic_head (Grob_info info) { - if (info.music_cause ()) + if (info.event_cause ()) { for (vsize i = 0; i < scripts_.size (); i++) { @@ -246,8 +245,6 @@ Script_engraver::stop_translation_timestep () scripts_.clear (); } -#include "translator.icc" - ADD_ACKNOWLEDGER (Script_engraver, slur); ADD_ACKNOWLEDGER (Script_engraver, rhythmic_head); ADD_ACKNOWLEDGER (Script_engraver, stem); diff --git a/lily/simple-closure.cc b/lily/simple-closure.cc index 40efbdd727..db19cfc38c 100644 --- a/lily/simple-closure.cc +++ b/lily/simple-closure.cc @@ -107,4 +107,4 @@ void init_simple_closure () -ADD_SCM_INIT_FUNC(simple_closure, init_simple_closure); +ADD_SCM_INIT_FUNC (simple_closure, init_simple_closure); diff --git a/lily/slash-repeat-engraver.cc b/lily/slash-repeat-engraver.cc index aa5b52c405..18d5312311 100644 --- a/lily/slash-repeat-engraver.cc +++ b/lily/slash-repeat-engraver.cc @@ -6,15 +6,18 @@ (c) 2000--2006 Han-Wen Nienhuys , Erik Sandberg */ -#include "repeated-music.hh" +#include "bar-line.hh" #include "global-context.hh" -#include "warn.hh" -#include "misc.hh" -#include "spanner.hh" #include "item.hh" +#include "misc.hh" #include "percent-repeat-iterator.hh" -#include "bar-line.hh" +#include "repeated-music.hh" #include "score-engraver.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "warn.hh" + +#include "translator.icc" /** This acknowledges repeated music with "percent" style. It typesets @@ -25,9 +28,9 @@ class Slash_repeat_engraver : public Engraver public: TRANSLATOR_DECLARATIONS (Slash_repeat_engraver); protected: - Music *slash_; + Stream_event *slash_; protected: - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (percent); void process_music (); }; @@ -36,24 +39,16 @@ Slash_repeat_engraver::Slash_repeat_engraver () slash_ = 0; } -bool -Slash_repeat_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Slash_repeat_engraver, percent); +void +Slash_repeat_engraver::listen_percent (Stream_event *ev) { /*todo: separate events for percent and slash */ - if (m->is_mus_type ("percent-event")) - { - Moment meas_length - = robust_scm2moment (get_property ("measureLength"), Moment (0)); - - if (m->get_length () < meas_length) - slash_ = m; - else - return false; - - return true; - } - - return false; + Moment meas_length + = robust_scm2moment (get_property ("measureLength"), Moment (0)); + + if (get_event_length (ev) < meas_length) + slash_ = ev; } void @@ -66,8 +61,6 @@ Slash_repeat_engraver::process_music () } } -#include "translator.icc" - ADD_TRANSLATOR (Slash_repeat_engraver, /* doc */ "Make beat repeats.", /* create */ "RepeatSlash", diff --git a/lily/slur-engraver.cc b/lily/slur-engraver.cc index dca3a3dc90..fb7a9e67c6 100644 --- a/lily/slur-engraver.cc +++ b/lily/slur-engraver.cc @@ -14,8 +14,11 @@ #include "note-column.hh" #include "slur.hh" #include "spanner.hh" +#include "stream-event.hh" #include "warn.hh" +#include "translator.icc" + /* It is possible that a slur starts and ends on the same note. At least, it is for phrasing slurs: a note can be both beginning and @@ -23,16 +26,15 @@ */ class Slur_engraver : public Engraver { - Drul_array events_; - Music *running_slur_start_; + Drul_array events_; + Stream_event *running_slur_start_; vector slurs_; vector end_slurs_; void set_melisma (bool); protected: - virtual bool try_music (Music *); - + DECLARE_TRANSLATOR_LISTENER (slur); DECLARE_ACKNOWLEDGER (accidental); DECLARE_ACKNOWLEDGER (dynamic_line_spanner); DECLARE_ACKNOWLEDGER (fingering); @@ -55,24 +57,15 @@ Slur_engraver::Slur_engraver () events_[START] = events_[STOP] = 0; } -bool -Slur_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, slur); +void +Slur_engraver::listen_slur (Stream_event *ev) { - if (m->is_mus_type ("slur-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); - if (d == START) - { - events_[START] = m; - return true; - } - else if (d == STOP) - { - events_[STOP] = m; - return true; - } - } - return false; + Direction d = to_dir (ev->get_property ("span-direction")); + if (d == START) + events_[START] = ev; + else if (d == STOP) + events_[STOP] = ev; } void @@ -163,7 +156,7 @@ Slur_engraver::process_music () if (events_[START] && slurs_.empty ()) { - Music *ev = events_[START]; + Stream_event *ev = events_[START]; bool double_slurs = to_boolean (get_property ("doubleSlurs")); @@ -194,8 +187,6 @@ Slur_engraver::stop_translation_timestep () events_[START] = events_[STOP] = 0; } -#include "translator.icc" - ADD_ACKNOWLEDGER (Slur_engraver, accidental); ADD_ACKNOWLEDGER (Slur_engraver, dynamic_line_spanner); ADD_ACKNOWLEDGER (Slur_engraver, fingering); diff --git a/lily/spacing-engraver.cc b/lily/spacing-engraver.cc index b3ca575393..9325451d28 100644 --- a/lily/spacing-engraver.cc +++ b/lily/spacing-engraver.cc @@ -6,13 +6,14 @@ (c) 1999--2006 Han-Wen Nienhuys */ -#include "paper-column.hh" #include "engraver.hh" -#include "pqueue.hh" #include "note-spacing.hh" -#include "staff-spacing.hh" +#include "paper-column.hh" #include "pointer-group-interface.hh" +#include "pqueue.hh" #include "spanner.hh" +#include "staff-spacing.hh" +#include "stream-event.hh" #include "translator.icc" @@ -58,7 +59,7 @@ class Spacing_engraver : public Engraver vector stopped_durations_; Moment now_; Spanner *spacing_; - Music *start_section_; + Stream_event *start_section_; TRANSLATOR_DECLARATIONS (Spacing_engraver); @@ -66,13 +67,13 @@ protected: DECLARE_ACKNOWLEDGER (staff_spacing); DECLARE_ACKNOWLEDGER (note_spacing); DECLARE_ACKNOWLEDGER (rhythmic_head); + DECLARE_TRANSLATOR_LISTENER (spacing_section); void start_translation_timestep (); void stop_translation_timestep (); void process_music (); virtual void finalize (); - virtual bool try_music (Music *m); void start_spanner (); void stop_spanner (); @@ -84,11 +85,11 @@ Spacing_engraver::Spacing_engraver () start_section_ = 0; } -bool -Spacing_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Spacing_engraver, spacing_section); +void +Spacing_engraver::listen_spacing_section (Stream_event *ev) { - start_section_ = m; - return true; + start_section_ = ev; } void @@ -153,10 +154,10 @@ Spacing_engraver::acknowledge_rhythmic_head (Grob_info i) */ if (!now_.grace_part_) { - Music *r = i.music_cause (); - if (r && r->is_mus_type ("rhythmic-event")) + Stream_event *r = i.event_cause (); + if (r && r->in_event_class ("rhythmic-event")) { - Moment len = r->get_length (); + Moment len = get_event_length (r); Rhythmic_tuple t (i, now_mom () + len); now_durations_.push_back (t); } @@ -181,10 +182,10 @@ Spacing_engraver::stop_translation_timestep () shortest_playing.set_infinite (1); for (vsize i = 0; i < playing_durations_.size (); i++) { - Music *mus = playing_durations_[i].info_.music_cause (); - if (mus) + Stream_event *ev = playing_durations_[i].info_.event_cause (); + if (ev) { - Moment m = mus->get_length (); + Moment m = get_event_length (ev); shortest_playing = min (shortest_playing, m); } } @@ -193,7 +194,7 @@ Spacing_engraver::stop_translation_timestep () for (vsize i = 0; i < now_durations_.size (); i++) { - Moment m = now_durations_[i].info_.music_cause ()->get_length (); + Moment m = get_event_length (now_durations_[i].info_.event_cause ()); if (m.to_bool ()) { starter = min (starter, m); diff --git a/lily/staff-symbol-engraver.cc b/lily/staff-symbol-engraver.cc index c147d54dff..d4e57955fc 100644 --- a/lily/staff-symbol-engraver.cc +++ b/lily/staff-symbol-engraver.cc @@ -6,8 +6,13 @@ (c) 1997--2006 Han-Wen Nienhuys */ -#include "spanner.hh" #include "engraver.hh" +#include "international.hh" +#include "spanner.hh" +#include "stream-event.hh" +#include "warn.hh" + +#include "translator.icc" class Staff_symbol_engraver : public Engraver { @@ -15,7 +20,7 @@ public: TRANSLATOR_DECLARATIONS (Staff_symbol_engraver); protected: - Drul_array span_events_; + Drul_array span_events_; Spanner *span_; Spanner *finished_span_; bool first_start_; @@ -25,9 +30,9 @@ protected: virtual void stop_spanner (); void stop_translation_timestep (); - virtual bool try_music (Music *); virtual ~Staff_symbol_engraver (); DECLARE_ACKNOWLEDGER (grob); + DECLARE_TRANSLATOR_LISTENER (staff_span); virtual void finalize (); void process_music (); }; @@ -46,17 +51,15 @@ Staff_symbol_engraver::Staff_symbol_engraver () span_events_[RIGHT] = 0; } -bool -Staff_symbol_engraver::try_music (Music *music) +IMPLEMENT_TRANSLATOR_LISTENER (Staff_symbol_engraver, staff_span); +void +Staff_symbol_engraver::listen_staff_span (Stream_event *ev) { - Direction d = to_dir (music->get_property ("span-direction")); + Direction d = to_dir (ev->get_property ("span-direction")); if (d) - { - span_events_[d] = music; - return true; - } - - return false; + span_events_[d] = ev; + else + programming_error (_ ("staff-span event has no direction")); } void @@ -142,8 +145,6 @@ Staff_symbol_engraver::acknowledge_grob (Grob_info s) } } -#include "translator.icc" - ADD_ACKNOWLEDGER (Staff_symbol_engraver, grob); ADD_TRANSLATOR (Staff_symbol_engraver, diff --git a/lily/stem-engraver.cc b/lily/stem-engraver.cc index 797406b4fb..6a69aaa649 100644 --- a/lily/stem-engraver.cc +++ b/lily/stem-engraver.cc @@ -19,6 +19,9 @@ #include "staff-symbol-referencer.hh" #include "stem-tremolo.hh" #include "stem.hh" +#include "stream-event.hh" + +#include "translator.icc" /** Make stems upon receiving noteheads. @@ -27,17 +30,17 @@ class Stem_engraver : public Engraver { Grob *stem_; Grob *tremolo_; - Music *rhythmic_ev_; - Music *tremolo_ev_; + Stream_event *rhythmic_ev_; + Stream_event *tremolo_ev_; TRANSLATOR_DECLARATIONS (Stem_engraver); protected: void make_stem (Grob_info); + DECLARE_TRANSLATOR_LISTENER (tremolo); DECLARE_ACKNOWLEDGER (rhythmic_head); void stop_translation_timestep (); - virtual bool try_music (Music *); }; Stem_engraver::Stem_engraver () @@ -59,8 +62,8 @@ Stem_engraver::make_stem (Grob_info gi) we take the duration log from the Event, since the duration-log for a note head is always <= 2. */ - Music *music = gi.music_cause (); - Duration *dur = unsmob_duration (music->get_property ("duration")); + Stream_event *ev = gi.event_cause (); + Duration *dur = unsmob_duration (ev->get_property ("duration")); stem_->set_property ("duration-log", dur ? scm_from_int (dur->duration_log ()) : 0); @@ -114,7 +117,7 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi) if (Rhythmic_head::get_stem (gi.grob ())) return; - Music *cause = gi.music_cause (); + Stream_event *cause = gi.event_cause (); if (!cause) return; Duration *d = unsmob_duration (cause->get_property ("duration")); @@ -127,9 +130,9 @@ Stem_engraver::acknowledge_rhythmic_head (Grob_info gi) if (Stem::duration_log (stem_) != d->duration_log ()) { // FIXME: - gi.music_cause ()->origin ()->warning (_f ("adding note head to incompatible stem (type = %d)", + gi.event_cause ()->origin ()->warning (_f ("adding note head to incompatible stem (type = %d)", 1 << Stem::duration_log (stem_))); - gi.music_cause ()->origin ()->warning (_f ("maybe input should specify polyphonic voices")); + gi.event_cause ()->origin ()->warning (_f ("maybe input should specify polyphonic voices")); } Stem::add_head (stem_, gi.grob ()); @@ -159,19 +162,13 @@ Stem_engraver::stop_translation_timestep () tremolo_ev_ = 0; } -bool -Stem_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Stem_engraver, tremolo); +void +Stem_engraver::listen_tremolo (Stream_event *ev) { - if (m->is_mus_type ("tremolo-event")) - { - tremolo_ev_ = m; - return true; - } - return false; + tremolo_ev_ = ev; } -#include "translator.icc" - ADD_ACKNOWLEDGER (Stem_engraver, rhythmic_head); ADD_TRANSLATOR (Stem_engraver, diff --git a/lily/tab-note-heads-engraver.cc b/lily/tab-note-heads-engraver.cc index b6f3f4ced9..1ddabdd697 100644 --- a/lily/tab-note-heads-engraver.cc +++ b/lily/tab-note-heads-engraver.cc @@ -10,16 +10,19 @@ #include using namespace std; -#include "rhythmic-head.hh" -#include "output-def.hh" -#include "music.hh" -#include "dots.hh" #include "dot-column.hh" -#include "staff-symbol-referencer.hh" +#include "dots.hh" +#include "duration.hh" #include "item.hh" +#include "music.hh" +#include "output-def.hh" +#include "rhythmic-head.hh" #include "score-engraver.hh" +#include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "warn.hh" -#include "duration.hh" + +#include "translator.icc" /** make (guitar-like) tablature note @@ -29,13 +32,14 @@ class Tab_note_heads_engraver : public Engraver vector notes_; vector dots_; - vector note_events_; - vector tabstring_events_; + vector note_events_; + vector tabstring_events_; public: TRANSLATOR_DECLARATIONS (Tab_note_heads_engraver); protected: - virtual bool try_music (Music *event); + DECLARE_TRANSLATOR_LISTENER (note); + DECLARE_TRANSLATOR_LISTENER (string_number); void process_music (); void stop_translation_timestep (); @@ -45,21 +49,18 @@ Tab_note_heads_engraver::Tab_note_heads_engraver () { } -bool -Tab_note_heads_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, note); +void +Tab_note_heads_engraver::listen_note (Stream_event *ev) { - if (m->is_mus_type ("note-event")) - { - note_events_.push_back (m); - return true; - } - else if (m->is_mus_type ("string-number-event")) - { - tabstring_events_.push_back (m); - return true; - } + note_events_.push_back (ev); +} - return false; +IMPLEMENT_TRANSLATOR_LISTENER (Tab_note_heads_engraver, string_number); +void +Tab_note_heads_engraver::listen_string_number (Stream_event *ev) +{ + tabstring_events_.push_back (ev); } void @@ -72,10 +73,10 @@ Tab_note_heads_engraver::process_music () int number_of_strings = ((int) ly_length (stringTunings)); bool high_string_one = to_boolean (get_property ("highStringOne")); - Music *event = note_events_[i]; + Stream_event *event = note_events_[i]; Item *note = make_item ("TabNoteHead", event->self_scm ()); - Music *tabstring_event = 0; + Stream_event *tabstring_event = 0; for (SCM s = event->get_property ("articulations"); !tabstring_event && scm_is_pair (s); s = scm_cdr (s)) @@ -83,7 +84,7 @@ Tab_note_heads_engraver::process_music () Music *art = unsmob_music (scm_car (s)); if (art->is_mus_type ("string-number-event")) - tabstring_event = art; + tabstring_event = art->to_event (); } if (!tabstring_event && j < tabstring_events_.size ()) @@ -161,8 +162,6 @@ Tab_note_heads_engraver::stop_translation_timestep () tabstring_events_.clear (); } -#include "translator.icc" - ADD_TRANSLATOR (Tab_note_heads_engraver, /* doc */ "Generate one or more tablature noteheads from Music of type NoteEvent.", /* create */ "TabNoteHead Dots", diff --git a/lily/text-engraver.cc b/lily/text-engraver.cc index 6a59be8664..2c86f50d67 100644 --- a/lily/text-engraver.cc +++ b/lily/text-engraver.cc @@ -8,39 +8,38 @@ #include "directional-element-interface.hh" #include "engraver.hh" +#include "rhythmic-head.hh" #include "side-position-interface.hh" #include "stem.hh" -#include "rhythmic-head.hh" +#include "stream-event.hh" #include "text-interface.hh" +#include "translator.icc" + /** typeset directions that are plain text. */ class Text_engraver : public Engraver { - vector evs_; + vector evs_; vector texts_; public: TRANSLATOR_DECLARATIONS (Text_engraver); protected: - virtual bool try_music (Music *m); void stop_translation_timestep (); void process_acknowledged (); + DECLARE_TRANSLATOR_LISTENER (text_script); DECLARE_ACKNOWLEDGER (stem_tremolo); DECLARE_ACKNOWLEDGER (stem); DECLARE_ACKNOWLEDGER (rhythmic_head); }; -bool -Text_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Text_engraver, text_script); +void +Text_engraver::listen_text_script (Stream_event *ev) { - if (m->is_mus_type ("text-script-event")) - { - evs_.push_back (m); - return true; - } - return false; + evs_.push_back (ev); } void @@ -84,7 +83,7 @@ Text_engraver::process_acknowledged () return; for (vsize i = 0; i < evs_.size (); i++) { - Music *r = evs_[i]; + Stream_event *r = evs_[i]; // URG: Text vs TextScript Item *text = make_item ("TextScript", r->self_scm ()); @@ -125,8 +124,6 @@ Text_engraver::Text_engraver () { } -#include "translator.icc" - ADD_ACKNOWLEDGER (Text_engraver, stem); ADD_ACKNOWLEDGER (Text_engraver, stem_tremolo); ADD_ACKNOWLEDGER (Text_engraver, rhythmic_head); diff --git a/lily/text-spanner-engraver.cc b/lily/text-spanner-engraver.cc index d5212ded7f..b7628c325c 100644 --- a/lily/text-spanner-engraver.cc +++ b/lily/text-spanner-engraver.cc @@ -11,6 +11,9 @@ #include "international.hh" #include "note-column.hh" #include "side-position-interface.hh" +#include "stream-event.hh" + +#include "translator.icc" class Text_spanner_engraver : public Engraver { @@ -19,15 +22,15 @@ public: protected: virtual void finalize (); DECLARE_ACKNOWLEDGER (note_column); - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (text_span); void stop_translation_timestep (); void process_music (); private: Spanner *span_; Spanner *finished_; - Music *current_event_; - Drul_array event_drul_; + Stream_event *current_event_; + Drul_array event_drul_; void typeset_all (); }; @@ -40,17 +43,12 @@ Text_spanner_engraver::Text_spanner_engraver () event_drul_[STOP] = 0; } -bool -Text_spanner_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Text_spanner_engraver, text_span); +void +Text_spanner_engraver::listen_text_span (Stream_event *ev) { - if (m->is_mus_type ("text-span-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); - event_drul_[d] = m; - return true; - } - - return false; + Direction d = to_dir (ev->get_property ("span-direction")); + event_drul_[d] = ev; } void @@ -137,7 +135,6 @@ Text_spanner_engraver::finalize () } } -#include "translator.icc" ADD_ACKNOWLEDGER (Text_spanner_engraver, note_column); ADD_TRANSLATOR (Text_spanner_engraver, /* doc */ "Create text spanner from a Music.", diff --git a/lily/tie-engraver.cc b/lily/tie-engraver.cc index 2341c3d08e..3496686fff 100644 --- a/lily/tie-engraver.cc +++ b/lily/tie-engraver.cc @@ -21,6 +21,8 @@ #include "tie.hh" #include "warn.hh" +#include "translator.icc" + /** Manufacture ties. Acknowledge noteheads, and put them into a priority queue. If we have a TieEvent, connect the notes that finish @@ -35,7 +37,7 @@ struct Head_event_tuple Grob *head_; Moment end_moment_; SCM tie_definition_; - Music *event_; + Stream_event *event_; Head_event_tuple () { @@ -47,7 +49,7 @@ struct Head_event_tuple class Tie_engraver : public Engraver { - Music *event_; + Stream_event *event_; vector now_heads_; vector heads_to_tie_; vector ties_; @@ -59,7 +61,7 @@ protected: virtual void derived_mark () const; void start_translation_timestep (); DECLARE_ACKNOWLEDGER (note_head); - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (tie); void process_music (); void typeset_tie (Grob *); public: @@ -80,13 +82,11 @@ Tie_engraver::Tie_engraver () tie_column_ = 0; } -bool -Tie_engraver::try_music (Music *mus) +IMPLEMENT_TRANSLATOR_LISTENER (Tie_engraver, tie); +void +Tie_engraver::listen_tie (Stream_event *ev) { - if (mus->is_mus_type ("tie-event")) - event_ = mus; - - return true; + event_ = ev; } void @@ -228,8 +228,6 @@ Tie_engraver::typeset_tie (Grob *her) sp->set_bound (RIGHT, new_head_drul[RIGHT]); } -#include "translator.icc" - ADD_ACKNOWLEDGER (Tie_engraver, note_head); ADD_TRANSLATOR (Tie_engraver, /* doc */ "Generate ties between noteheads of equal pitch.", diff --git a/lily/time-scaled-music-iterator.cc b/lily/time-scaled-music-iterator.cc index ccc93d0314..9ab2673eeb 100644 --- a/lily/time-scaled-music-iterator.cc +++ b/lily/time-scaled-music-iterator.cc @@ -14,7 +14,7 @@ #include "sequential-iterator.hh" /* - Iterates \times, by sending TupletEvents at the start/end of each + Iterates \times, by sending TupletSpanEvents at the start/end of each tuplet bracket. Extra stop/start events are sent at regular intervals if tupletSpannerDuration is set. */ @@ -96,7 +96,7 @@ Time_scaled_music_iterator::construct_children () Music *mus = get_music (); Input *origin = mus->origin (); - SCM tuplet_symbol = ly_symbol2scm ("TupletEvent"); + SCM tuplet_symbol = ly_symbol2scm ("TupletSpanEvent"); SCM start_scm = scm_call_2 (ly_lily_module_constant ("make-span-event"), tuplet_symbol, scm_from_int (START)); start_ = unsmob_music (start_scm); start_->set_spot (*origin); diff --git a/lily/translator.cc b/lily/translator.cc index 6eab93b9a8..cf07d527e8 100644 --- a/lily/translator.cc +++ b/lily/translator.cc @@ -8,11 +8,12 @@ #include "translator.hh" -#include "warn.hh" -#include "translator-group.hh" #include "context-def.hh" #include "dispatcher.hh" #include "global-context.hh" +#include "international.hh" +#include "translator-group.hh" +#include "warn.hh" #include "translator.icc" #include "ly-smobs.icc" @@ -129,6 +130,15 @@ Translator::disconnect_from_context (Context *c) c->events_below ()->remove_listener (r->get_listener_ (this), r->event_class_); } +static SCM listened_event_classes = SCM_EOL; + +LY_DEFINE (ly_get_listened_event_classes, "ly:get-listened-event-classes", + 0, 0, 0, (), + "Returns a list of all event classes that some translator listens to.") +{ + return listened_event_classes; +} + /* Internally called once, statically, for each translator listener. Connects the name of an event class with a procedure that @@ -149,7 +159,9 @@ Translator::add_translator_listener (translator_listener_record **listener_list, name = name + "-event"; /* It's OK to use scm_gc_protect_object for protection, because r is statically allocated. */ - r->event_class_ = scm_gc_protect_object (scm_str2symbol (name.c_str ())); + SCM class_sym = scm_gc_protect_object (scm_str2symbol (name.c_str ())); + listened_event_classes = scm_gc_protect_object (scm_cons (class_sym, listened_event_classes)); + r->event_class_ = class_sym; r->get_listener_ = get_listener; r->next_ = *listener_list; *listener_list = r; @@ -241,6 +253,37 @@ get_event_length (Stream_event *e) return Moment (0); } +/* + Helper, used through ASSIGN_EVENT_ONCE to throw warnings for + simultaneous events. The helper is only useful in listen_* methods + of translators. +*/ +bool +internal_event_assignment (Stream_event **old_ev, Stream_event *new_ev, const char *function) +{ + if (*old_ev) + { + /* extract event class from function name */ + const char *prefix = "listen_"; + assert (!strncmp (function, "listen_", strlen (prefix))); + function += strlen (prefix); + char ev_class[strlen (function) + 1]; + strcpy (ev_class, function); + for (char *c = ev_class; *c; c++) + if (*c == '_') + *c = '-'; + + new_ev->origin ()->warning (_f ("Two simultaneous %s events, junking this one", ev_class)); + (*old_ev)->origin ()->warning (_f ("Previous %s event here", ev_class)); + return false; + } + else + { + *old_ev = new_ev; + return true; + } +} + ADD_TRANSLATOR (Translator, "Base class. Unused", "", diff --git a/lily/trill-spanner-engraver.cc b/lily/trill-spanner-engraver.cc index 5a4d099bda..54d3daa96b 100644 --- a/lily/trill-spanner-engraver.cc +++ b/lily/trill-spanner-engraver.cc @@ -18,6 +18,7 @@ #include "international.hh" #include "note-column.hh" #include "side-position-interface.hh" +#include "stream-event.hh" #include "translator.icc" @@ -28,15 +29,15 @@ public: protected: virtual void finalize (); DECLARE_ACKNOWLEDGER (note_column); - virtual bool try_music (Music *); + DECLARE_TRANSLATOR_LISTENER (trill_span); void stop_translation_timestep (); void process_music (); private: Spanner *span_; Spanner *finished_; - Music *current_event_; - Drul_array event_drul_; + Stream_event *current_event_; + Drul_array event_drul_; void typeset_all (); }; @@ -49,17 +50,12 @@ Trill_spanner_engraver::Trill_spanner_engraver () event_drul_[STOP] = 0; } -bool -Trill_spanner_engraver::try_music (Music *m) +IMPLEMENT_TRANSLATOR_LISTENER (Trill_spanner_engraver, trill_span); +void +Trill_spanner_engraver::listen_trill_span (Stream_event *ev) { - if (m->is_mus_type ("trill-span-event")) - { - Direction d = to_dir (m->get_property ("span-direction")); - event_drul_[d] = m; - return true; - } - - return false; + Direction d = to_dir (ev->get_property ("span-direction")); + event_drul_[d] = ev; } void diff --git a/lily/tuplet-engraver.cc b/lily/tuplet-engraver.cc index a588f48571..a160d0e444 100644 --- a/lily/tuplet-engraver.cc +++ b/lily/tuplet-engraver.cc @@ -11,12 +11,13 @@ #include "beam.hh" #include "engraver.hh" #include "spanner.hh" +#include "stream-event.hh" #include "translator.icc" struct Tuplet_description { - Music *music_; + Stream_event *event_; Spanner *bracket_; Spanner *number_; @@ -25,9 +26,9 @@ struct Tuplet_description Tuplet_description () { + event_ = 0; full_length_note_ = false; full_length_ = false; - music_ = 0; bracket_ = 0; number_ = 0; } @@ -43,32 +44,28 @@ protected: vector stopped_tuplets_; vector last_tuplets_; DECLARE_ACKNOWLEDGER (note_column); - virtual bool try_music (Music *r); + DECLARE_TRANSLATOR_LISTENER (tuplet_span); virtual void finalize (); void start_translation_timestep (); void process_music (); }; -bool -Tuplet_engraver::try_music (Music *music) +IMPLEMENT_TRANSLATOR_LISTENER (Tuplet_engraver, tuplet_span); +void +Tuplet_engraver::listen_tuplet_span (Stream_event *ev) { - if (music->is_mus_type ("tuplet-spanner-event")) + Direction dir = to_dir (ev->get_property ("span-direction")); + if (dir == START) { - Direction dir = to_dir (music->get_property ("span-direction")); - if (dir == START) - { - Tuplet_description d; - d.music_ = music; - tuplets_.push_back (d); - } - if (dir == STOP) - { - stopped_tuplets_.push_back (tuplets_.back ()); - tuplets_.pop_back (); - } - return true; + Tuplet_description d; + d.event_ = ev; + tuplets_.push_back (d); + } + if (dir == STOP) + { + stopped_tuplets_.push_back (tuplets_.back ()); + tuplets_.pop_back (); } - return false; } void @@ -117,9 +114,9 @@ Tuplet_engraver::process_music () = to_boolean (get_property ("tupletFullLengthNote")); tuplets_[i].bracket_ = make_spanner ("TupletBracket", - tuplets_[i].music_->self_scm ()); + tuplets_[i].event_->self_scm ()); tuplets_[i].number_ = make_spanner ("TupletNumber", - tuplets_[i].music_->self_scm ()); + tuplets_[i].event_->self_scm ()); tuplets_[i].number_->set_object ("bracket", tuplets_[i].bracket_->self_scm ()); tuplets_[i].bracket_->set_object ("tuplet-number", tuplets_[i].number_->self_scm ()); @@ -169,6 +166,6 @@ ADD_ACKNOWLEDGER (Tuplet_engraver, note_column); ADD_TRANSLATOR (Tuplet_engraver, /* doc */ "Catch TupletSpannerEvent and generate appropriate bracket ", /* create */ "TupletBracket TupletNumber ", - /* accept */ "tuplet-spanner-event", + /* accept */ "tuplet-span-event", /* read */ "tupletFullLength ", /* write */ ""); diff --git a/lily/vaticana-ligature-engraver.cc b/lily/vaticana-ligature-engraver.cc index 6bfd470c09..f84ecaa6b2 100644 --- a/lily/vaticana-ligature-engraver.cc +++ b/lily/vaticana-ligature-engraver.cc @@ -15,6 +15,7 @@ #include "paper-column.hh" #include "spanner.hh" #include "staff-symbol-referencer.hh" +#include "stream-event.hh" #include "vaticana-ligature.hh" #include "warn.hh" @@ -45,8 +46,24 @@ protected: virtual Spanner *create_ligature_spanner (); virtual void transform_heads (Spanner *ligature, vector primitives); + DECLARE_TRANSLATOR_LISTENER (pes_or_flexa); + DECLARE_TRANSLATOR_LISTENER (ligature); }; +IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, pes_or_flexa); +void +Vaticana_ligature_engraver::listen_pes_or_flexa (Stream_event *ev) +{ + Gregorian_ligature_engraver::listen_pes_or_flexa (ev); +} + +IMPLEMENT_TRANSLATOR_LISTENER (Vaticana_ligature_engraver, ligature); +void +Vaticana_ligature_engraver::listen_ligature (Stream_event *ev) +{ + Ligature_engraver::listen_ligature (ev); +} + Vaticana_ligature_engraver::Vaticana_ligature_engraver () { brew_ligature_primitive_proc = diff --git a/ly/declarations-init.ly b/ly/declarations-init.ly index 5a322c2af7..027849b88c 100644 --- a/ly/declarations-init.ly +++ b/ly/declarations-init.ly @@ -71,8 +71,9 @@ escapedSmallerSymbol = #(make-span-event 'CrescendoEvent START) \include "scale-definitions-init.ly" -melisma = #(make-span-event 'ManualMelismaEvent START) -melismaEnd = #(make-span-event 'ManualMelismaEvent STOP) +melisma = #(context-spec-music (make-property-set 'melismaBusy #t) 'Bottom) +melismaEnd = #(context-spec-music (make-property-unset 'melismaBusy) 'Bottom) + laissezVibrer = #(make-music 'LaissezVibrerEvent) repeatTie = #(make-music 'RepeatTieEvent) diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index cba936c6f9..a9e4b53d75 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -205,7 +205,6 @@ contained staves are not connected vertically." \consists "Chord_tremolo_engraver" \consists "Percent_repeat_engraver" \consists "Slash_repeat_engraver" - \consists "Melisma_translator" \consists "Part_combine_engraver" \consists "Text_engraver" diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 8668acafd9..ed1cb875dd 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -40,7 +40,6 @@ \consists "Note_performer" \consists "Beam_performer" \consists "Slur_performer" - \consists "Melisma_translator" } \context { diff --git a/scm/autochange.scm b/scm/autochange.scm index b7169c8a99..e4a27d7063 100644 --- a/scm/autochange.scm +++ b/scm/autochange.scm @@ -11,10 +11,10 @@ (evs (map car (cdar event-list))) (now (car now-tun)) (notes (filter (lambda (x) - (equal? (ly:music-property x 'name) 'NoteEvent)) + (equal? (ly:event-property x 'class) 'note-event)) evs)) (pitch (if (pair? notes) - (ly:music-property (car notes) 'pitch) + (ly:event-property (car notes) 'pitch) #f))) ;; tail recursive. (if (and pitch (not (= (ly:pitch-steps pitch) 0))) @@ -30,17 +30,16 @@ (if pitch #f now) (cdr event-list) acc))))) - (set! noticed '()) (let* ((m (make-music 'AutoChangeMusic)) - (context (ly:run-translator (make-non-relative-music music) part-combine-listener)) - (evs (last-pair noticed)) + (m1 (make-non-relative-music (context-spec-music music 'Voice "one"))) + (context-list (recording-group-emulate music part-combine-listener)) + (evs (car context-list)) + (rev (reverse! (cdar context-list))) (split (reverse! (generate-split-list #f - (if (pair? evs) - (reverse! (cdar evs) '()) '()) + rev '()) '()))) (set! (ly:music-property m 'element) music) (set! (ly:music-property m 'split-list) split) - (set! noticed '()) m)) diff --git a/scm/define-event-classes.scm b/scm/define-event-classes.scm index f70e4d57c3..3bb654ada0 100644 --- a/scm/define-event-classes.scm +++ b/scm/define-event-classes.scm @@ -7,26 +7,41 @@ (use-modules (srfi srfi-1)) -;; Event class hierarchy. Each line is on the form ((List of children) . Parent) +;; Event class hierarchy. Each line is on the form (Parent . (List of children)) (define event-classes - '(((StreamEvent) . '()) - ((RemoveContext ChangeParent Override Revert UnsetProperty - SetProperty MusicEvent OldMusicEvent CreateContext Prepare - OneTimeStep Finish) . StreamEvent) - ((arpeggio-event - beam-event note-event absolute-dynamic-event - key-change-event lyric-event pedal-event slur-event tie-event - metronome-change-event span-dynamic-event) - . MusicEvent) - ((decrescendo-event crescendo-event) . span-dynamic-event) - ((sostenuto-event sustain-event una-corda-event) . pedal-event) - ((Announcement) . '()) - ((AnnounceNewContext) . Announcement) + '((() . (StreamEvent)) + (StreamEvent . + (RemoveContext ChangeParent Override Revert UnsetProperty + SetProperty music-event OldMusicEvent CreateContext Prepare + OneTimeStep Finish)) + (music-event . (arpeggio-event breathing-event extender-event span-event + rhythmic-event dynamic-event break-event percent-event + key-change-event string-number-event tie-event part-combine-event + metronome-change-event beam-forbid-event script-event + tremolo-event bend-after-event fingering-event glissando-event + harmonic-event hyphen-event laissez-vibrer-event mark-event + multi-measure-text-event note-grouping-event + pes-or-flexa-event repeat-tie-event spacing-section-event + layout-instruction-event)) + (script-event . (articulation-event text-script-event)) + (part-combine-event . (solo1-event solo2-event unisono-event)) + (break-event . (line-break-event page-break-event page-turn-event)) + (dynamic-event . (absolute-dynamic-event)) + (span-event . (span-dynamic-event beam-event ligature-event + pedal-event phrasing-slur-event slur-event staff-span-event + text-span-event trill-span-event tremolo-span-event + tuplet-span-event)) + (span-dynamic-event . (decrescendo-event crescendo-event)) + (pedal-event . (sostenuto-event sustain-event una-corda-event)) + (rhythmic-event . (lyric-event melodic-event multi-measure-rest-event + rest-event skip-event bass-figure-event)) + (melodic-event . (cluster-note-event note-event)) + (() . (Announcement)) + (Announcement . (AnnounceNewContext)) )) ;; Maps event-class to a list of ancestors (inclusive) -;; TODO: use resizable hash -(define ancestor-lookup (make-hash-table 1)) +(define ancestor-lookup (make-hash-table)) ;; Each class will be defined as ;; (class parent grandparent .. ) @@ -35,14 +50,71 @@ (lambda (rel) (for-each (lambda (type) - (hashq-set! ancestor-lookup type (cons type (hashq-ref ancestor-lookup (cdr rel) '())))) ;; `(define ,type (cons ',type ,(cdr rel))))) - (car rel))) + (hashq-set! ancestor-lookup type + (cons type (hashq-ref ancestor-lookup (car rel) '())))) + (cdr rel))) event-classes) ;; TODO: Allow entering more complex classes, by taking unions. (define-public (ly:make-event-class leaf) (hashq-ref ancestor-lookup leaf)) -;; (primitive-eval leaf)) + +;; does this exist in guile already? +(define (map-tree f t) + (cond + ((list? t) + (map (lambda (x) (map-tree f x)) t)) + ((pair? t) + (cons (map-tree f (car t)) (map-tree f (cdr t)))) + (else (f t)))) + +;; expand each non-leaf subtree to (root . children), recursively +(define (expand-event-tree root) + (let ((children (assq root event-classes))) + (if children + (cons root (map expand-event-tree (cdr children))) + root))) + +;; All leaf event classes that no translator listens to +;; directly. Avoids printing a warning. +(define unlistened-music-event-classes + '(harmonic-event line-break-event page-break-event page-turn-event + solo1-event solo2-event skip-event unisono-event)) + +;; produce neater representation of music event tree. +;; TODO: switch to this representation for the event-classes list? +(define music-event-tree (expand-event-tree 'music-event)) +(define (sort-tree t) + (define (stringify el) + (if (symbol? el) + (symbol->string el) + (symbol->string (first el)))) + (if (list? t) + (sort (map (lambda (el) + (if (list? el) + (cons (car el) (sort-tree (cdr el))) + el)) + t) + (lambda (a b) (string)) (define (f? x) - (equal? (ly:music-property x 'name) 'NoteEvent)) + (equal? (ly:event-property x 'class) 'note-event)) (filter f? (events vs))) (define-method (previous-voice-state (vs )) @@ -116,20 +116,20 @@ Voice-state objects "Analyse EVS at INDEX, given state ACTIVE." (define (analyse-tie-start active ev) - (if (equal? (ly:music-property ev 'name) 'TieEvent) + (if (equal? (ly:event-property ev 'class) 'tie-event) (acons 'tie (split-index (vector-ref voice-state-vec index)) active) active)) (define (analyse-tie-end active ev) - (if (equal? (ly:music-property ev 'name) 'NoteEvent) + (if (equal? (ly:event-property ev 'class) 'note-event) (assoc-remove! active 'tie) active)) (define (analyse-absdyn-end active ev) - (if (or (equal? (ly:music-property ev 'name) 'AbsoluteDynamicEvent) - (and (equal? (ly:music-property ev 'name) 'CrescendoEvent) - (equal? STOP (ly:music-property ev 'span-direction)))) + (if (or (equal? (ly:event-property ev 'class) 'absolute-dynamic-event) + (and (equal? (ly:event-property ev 'class) 'crescendo-event) + (equal? STOP (ly:event-property ev 'span-direction)))) (assoc-remove! (assoc-remove! active 'cresc) 'decr) active)) @@ -139,14 +139,14 @@ Voice-state objects (else (< (cdr a) (cdr b))))) (define (analyse-span-event active ev) - (let* ((name (ly:music-property ev 'name)) - (key (cond ((equal? name 'SlurEvent) 'slur) - ((equal? name 'PhrasingSlurEvent) 'tie) - ((equal? name 'BeamEvent) 'beam) - ((equal? name 'CrescendoEvent) 'cresc) - ((equal? name 'DecrescendoEvent) 'decr) + (let* ((name (ly:event-property ev 'class)) + (key (cond ((equal? name 'slur-event) 'slur) + ((equal? name 'phrasing-slur-event) 'tie) + ((equal? name 'beam-event) 'beam) + ((equal? name 'crescendo-event) 'cresc) + ((equal? name 'decrescendo-event) 'decr) (else #f))) - (sp (ly:music-property ev 'span-direction))) + (sp (ly:event-property ev 'span-direction))) (if (and (symbol? key) (ly:dir? sp)) (if (= sp STOP) (assoc-remove! active key) @@ -184,7 +184,44 @@ Voice-state objects (helper 0 '())) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +(define-public (recording-group-emulate music odef) + "Interprets music according to odef, but stores all events in a chronological list, similar to the Recording_group_engraver in 2.8 and earlier" + (let* + ((context-list '()) + (now-mom (ly:make-moment 0 0)) + (global (ly:make-global-context odef)) + (mom-listener (ly:make-listener + (lambda (tev) + (set! now-mom (ly:event-property tev 'moment))))) + (new-context-listener + (ly:make-listener + (lambda (sev) + (let* + ((child (ly:event-property sev 'context)) + (this-moment-list + (cons (ly:context-id child) '())) + (dummy + (set! context-list (cons this-moment-list context-list))) + (acc '()) + (accumulate-event-listener + (ly:make-listener (lambda (ev) + (set! acc (cons (cons ev #t) acc))))) + (save-acc-listener (ly:make-listener (lambda (tev) + (if (pair? acc) + (let ((this-moment (cons (cons now-mom (ly:context-property child 'instrumentTransposition)) + acc))) + (set-cdr! this-moment-list (cons this-moment (cdr this-moment-list))) + (set! acc '()))))))) + (ly:add-listener accumulate-event-listener (ly:context-event-source child) 'music-event) + (ly:add-listener save-acc-listener (ly:context-event-source global) 'OneTimeStep)))))) + (ly:add-listener new-context-listener (ly:context-events-below global) 'AnnounceNewContext) + (ly:add-listener mom-listener (ly:context-event-source global) 'Prepare) + (ly:interpret-music-expression (make-non-relative-music music) global) + context-list)) + (define noticed '()) +;; todo: junk this, extract $defaultlayout from parser instead (define part-combine-listener '()) ; UGH - should pass noticed setter to part-combine-listener @@ -197,16 +234,15 @@ Voice-state objects (set! noticed (acons (ly:context-id context) lst noticed))) (define-public (make-part-combine-music music-list) - (let ((m (make-music 'PartCombineMusic)) - (m1 (make-non-relative-music (context-spec-music (car music-list) 'Voice "one"))) - (m2 (make-non-relative-music (context-spec-music (cadr music-list) 'Voice "two")))) + (let* ((m (make-music 'PartCombineMusic)) + (m1 (make-non-relative-music (context-spec-music (first music-list) 'Voice "one"))) + (m2 (make-non-relative-music (context-spec-music (second music-list) 'Voice "two"))) + (evs2 (recording-group-emulate m2 part-combine-listener)) + (evs1 (recording-group-emulate m1 part-combine-listener))) (set! (ly:music-property m 'elements) (list m1 m2)) - (ly:run-translator m2 part-combine-listener) - (ly:run-translator m1 part-combine-listener) (set! (ly:music-property m 'split-list) - (determine-split-list (reverse! (cdr (assoc "one" noticed)) '()) - (reverse! (cdr (assoc "two" noticed)) '()))) - (set! noticed '()) + (determine-split-list (reverse! (cdr (assoc "one" evs1)) '()) + (reverse! (cdr (assoc "two" evs2)) '()))) m)) (define-public (determine-split-list evl1 evl2) @@ -243,17 +279,17 @@ Only set if not set previously. (let* ((vs1 (car (voice-states now-state))) (vs2 (cdr (voice-states now-state))) (notes1 (note-events vs1)) - (durs1 (sort (map (lambda (x) (ly:music-property x 'duration)) + (durs1 (sort (map (lambda (x) (ly:event-property x 'duration)) notes1) ly:duration (length notes1) 1) (put 'apart)) @@ -327,8 +363,8 @@ Only set if not set previously. (notes2 (note-events vs2))) (cond ((and (= 1 (length notes1)) (= 1 (length notes2)) - (equal? (ly:music-property (car notes1) 'pitch) - (ly:music-property (car notes2) 'pitch))) + (equal? (ly:event-property (car notes1) 'pitch) + (ly:event-property (car notes2) 'pitch))) (set! (configuration now-state) 'unisono)) ((and (= 0 (length notes1)) (= 0 (length notes2))) @@ -457,13 +493,10 @@ the mark when there are no spanners active." (define-public (add-quotable name mus) (set! noticed '()) (let* ((tab (eval 'musicQuotes (current-module))) - (context (ly:run-translator (context-spec-music mus 'Voice) - part-combine-listener)) - (first-voice-handle (last-pair noticed))) - - (if (pair? first-voice-handle) + (context-list (recording-group-emulate (context-spec-music mus 'Voice) + part-combine-listener))) + (if (pair? context-list) (hash-set! tab name ;; cdr : skip name string - (list->vector (reverse! (cdar first-voice-handle) + (list->vector (reverse! (cdar context-list) '())))))) - -- cgit v1.2.3