]> git.donarmstrong.com Git - lilypond.git/commitdiff
Issue 4625/3: Listen to and record in-chord slurs
authorDavid Kastrup <dak@gnu.org>
Wed, 10 Dec 2014 17:44:16 +0000 (18:44 +0100)
committerDavid Kastrup <dak@gnu.org>
Mon, 5 Oct 2015 12:41:46 +0000 (14:41 +0200)
lily/include/slur-proto-engraver.hh
lily/phrasing-slur-engraver.cc
lily/slur-engraver.cc
lily/slur-proto-engraver.cc

index 4e9ab8ee8814f3cf7bdf2329de5ef11d3d881fe2..dc7566bc8a34bf7e3c956dedf559aae1c2dc2a0d 100644 (file)
@@ -32,9 +32,15 @@ protected:
       grob_name_ (grob_name), object_name_ (object_name),
       event_name_ (event_name) {}
 
+  struct Event_info {
+    Stream_event *slur_, *note_;
+    Event_info (Stream_event *slur, Stream_event *note)
+      : slur_ (slur), note_ (note)
+    { }
+  };
   // protected so that subclasses can see them
-  std::vector<Stream_event *> start_events_;
-  std::vector<Stream_event *> stop_events_;
+  std::vector<Event_info> start_events_;
+  std::vector<Event_info> stop_events_;
   std::vector<Grob *> slurs_;
   std::vector<Grob *> end_slurs_;
   std::vector<Grob_info> objects_to_acknowledge_;
@@ -53,7 +59,8 @@ protected:
   DECLARE_END_ACKNOWLEDGER (tie);
   DECLARE_ACKNOWLEDGER (tuplet_number);
 
-  void listen_slur (Stream_event *ev);
+  void listen_note (Stream_event *ev);
+  void listen_slur (Stream_event *ev, Stream_event *note = 0);
   void acknowledge_extra_object (Grob_info);
   void stop_translation_timestep ();
   void process_music ();
index 0a571dc79e29d6c9554a6510d293fc01907e932f..479be1df22cdf87e9d02e47c18d5c72cc0733dcf 100644 (file)
@@ -35,6 +35,7 @@ class Phrasing_slur_engraver : public Slur_proto_engraver
 {
 protected:
   DECLARE_TRANSLATOR_LISTENER (phrasing_slur);
+  DECLARE_TRANSLATOR_LISTENER (note);
   DECLARE_ACKNOWLEDGER (slur);
 
 public:
@@ -61,6 +62,13 @@ Phrasing_slur_engraver::listen_phrasing_slur (Stream_event *ev)
   Slur_proto_engraver::listen_slur (ev);
 }
 
+IMPLEMENT_TRANSLATOR_LISTENER (Phrasing_slur_engraver, note);
+void
+Phrasing_slur_engraver::listen_note (Stream_event *ev)
+{
+  Slur_proto_engraver::listen_note (ev);
+}
+
 void
 Phrasing_slur_engraver::acknowledge_slur (Grob_info info)
 {
index ed5fef7a562aee5e6a29a63edb3aa184c901a105..581136791d932daff6148c2ad80d2b82366c095b 100644 (file)
@@ -37,6 +37,7 @@ class Slur_engraver : public Slur_proto_engraver
 
 protected:
   DECLARE_TRANSLATOR_LISTENER (slur);
+  DECLARE_TRANSLATOR_LISTENER (note);
 
 public:
   SCM event_symbol ();
@@ -62,6 +63,13 @@ Slur_engraver::listen_slur (Stream_event *ev)
   Slur_proto_engraver::listen_slur (ev);
 }
 
+IMPLEMENT_TRANSLATOR_LISTENER (Slur_engraver, note);
+void
+Slur_engraver::listen_note (Stream_event *ev)
+{
+  Slur_proto_engraver::listen_note (ev);
+}
+
 void
 Slur_engraver::set_melisma (bool m)
 {
index a47db201621e8c0df850dea385437f4aadbb9c59..51160e2b3b89d409d04b788ca72a69314b27bf8d 100644 (file)
@@ -37,23 +37,41 @@ void
 Slur_proto_engraver::derived_mark () const
 {
   for (vsize i = start_events_.size (); i--;)
-    scm_gc_mark (start_events_[i]->self_scm ());
+    {
+      scm_gc_mark (start_events_[i].slur_->self_scm ());
+      scm_gc_mark (start_events_[i].note_->self_scm ());
+    }
   for (vsize i = stop_events_.size (); i--;)
-    scm_gc_mark (stop_events_[i]->self_scm ());
+    {
+      scm_gc_mark (stop_events_[i].slur_->self_scm ());
+      scm_gc_mark (stop_events_[i].note_->self_scm ());
+    }
 }
 
 void
-Slur_proto_engraver::listen_slur (Stream_event *ev)
+Slur_proto_engraver::listen_slur (Stream_event *ev, Stream_event *note)
 {
   Direction d = to_dir (ev->get_property ("span-direction"));
   if (d == START)
-    start_events_.push_back (ev);
+    start_events_.push_back (Event_info (ev, note));
   else if (d == STOP)
-    stop_events_.push_back (ev);
+    stop_events_.push_back (Event_info (ev, note));
   else ev->origin ()->warning (_f ("direction of %s invalid: %d",
                                      event_name_, int (d)));
 }
 
+void
+Slur_proto_engraver::listen_note (Stream_event *ev)
+{
+  for (SCM arts = ev->get_property ("articulations");
+       scm_is_pair (arts); arts = scm_cdr (arts))
+    {
+      Stream_event *art = unsmob<Stream_event> (scm_car (arts));
+      if (art->in_event_class (event_symbol ()))
+        listen_slur (art, ev);
+    }
+}
+
 void
 Slur_proto_engraver::acknowledge_note_column (Grob_info info)
 {
@@ -231,25 +249,27 @@ Slur_proto_engraver::process_music ()
 {
   for (vsize i = 0; i < stop_events_.size (); i++)
     {
-      string id = robust_scm2string (stop_events_[i]->get_property ("spanner-id"), "");
-      bool ended = try_to_end (stop_events_[i]);
+      string id = robust_scm2string
+        (stop_events_[i].slur_->get_property ("spanner-id"), "");
+      bool ended = try_to_end (stop_events_[i].slur_);
       if (ended)
         {
           // Ignore redundant stop events for this id
           for (vsize j = stop_events_.size (); --j > i;)
             {
-              if (id == robust_scm2string (stop_events_[j]->get_property ("spanner-id"), ""))
+              if (id == robust_scm2string
+                  (stop_events_[j].slur_->get_property ("spanner-id"), ""))
                 stop_events_.erase (stop_events_.begin () + j);
             }
         }
       else
-        stop_events_[i]->origin ()->warning (_f ("cannot end %s", object_name_));
+        stop_events_[i].slur_->origin ()->warning (_f ("cannot end %s", object_name_));
     }
 
   vsize old_slurs = slurs_.size ();
   for (vsize i = start_events_.size (); i--;)
     {
-      Stream_event *ev = start_events_[i];
+      Stream_event *ev = start_events_[i].slur_;
       string id = robust_scm2string (ev->get_property ("spanner-id"), "");
       Direction updown = to_dir (ev->get_property ("direction"));