From: Han-Wen Nienhuys <hanwen@xs4all.nl>
Date: Sun, 29 Sep 2002 17:16:18 +0000 (+0000)
Subject: add
X-Git-Tag: release/1.7.2~20
X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=d565eec0e4b9ecbfef333802a28435b1f54e8257;p=lilypond.git

add
---

diff --git a/ChangeLog b/ChangeLog
index 58f40e2a7b..36bf7a0cbf 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2002-09-29  Han-Wen Nienhuys  <hanwen@cs.uu.nl>
+
+	* lily/include/event-chord-iterator.hh,
+	lily/context-specced-music-iterator.cc,
+	lily/event.cc, lily/event-chord-iterator.cc: add
+
 2002-09-29  Jan Nieuwenhuizen  <janneke@gnu.org>
 
 
diff --git a/lily/context-specced-music-iterator.cc b/lily/context-specced-music-iterator.cc
new file mode 100644
index 0000000000..1fab03fe30
--- /dev/null
+++ b/lily/context-specced-music-iterator.cc
@@ -0,0 +1,41 @@
+/*   
+context-specced-music-iterator.cc --  implement 
+
+source file of the GNU LilyPond music typesetter
+
+(c) 2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+
+ */
+
+#include "music-wrapper-iterator.hh"
+#include "translator-group.hh"
+
+class Context_specced_music_iterator : public Music_wrapper_iterator
+{
+public:
+  VIRTUAL_COPY_CONS(Music_iterator);
+  DECLARE_SCHEME_CALLBACK(constructor,());
+  virtual void construct_children ();
+};
+
+void
+Context_specced_music_iterator::construct_children ()
+{
+  SCM ct = get_music ()->get_mus_property ("context-type");
+  String c_type;
+  if (gh_string_p (ct))
+    c_type =  ly_scm2string (ct);
+  
+  String c_id;
+  SCM ci = get_music ()->get_mus_property ("context-id");
+  if (gh_string_p (ci))
+    c_id = ly_scm2string (ci);
+  
+  Translator_group* a
+    =report_to ()->find_create_translator (c_type, c_id);
+  
+  set_translator (a);
+
+  Music_wrapper_iterator::construct_children();
+}
+IMPLEMENT_CTOR_CALLBACK(Context_specced_music_iterator);
diff --git a/lily/event-chord-iterator.cc b/lily/event-chord-iterator.cc
new file mode 100644
index 0000000000..ea9636d3b9
--- /dev/null
+++ b/lily/event-chord-iterator.cc
@@ -0,0 +1,82 @@
+/*
+  event-chord-iterator.cc -- implement Event_chord_iterator
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#include "translator-group.hh"
+#include "warn.hh"
+#include "event-chord-iterator.hh"
+#include "music-list.hh"
+#include "event.hh"
+
+Event_chord_iterator::Event_chord_iterator ()
+{
+}
+
+Event_chord_iterator::Event_chord_iterator (Event_chord_iterator const &src)
+  : Simple_music_iterator (src)
+{
+}
+
+Translator_group*
+Event_chord_iterator::get_req_translator ()
+{
+  assert (report_to ());
+  if (report_to ()->is_bottom_translator_b ())
+    return report_to ();
+
+  set_translator (report_to ()->get_default_interpreter ());
+  return report_to ();
+}
+
+void
+Event_chord_iterator::construct_children ()
+{
+  Simple_music_iterator::construct_children ();
+  get_req_translator ();
+}
+
+Event_chord*
+Event_chord_iterator::get_elt () const
+{
+  return (Event_chord*) get_music ();
+}
+
+SCM
+Event_chord_iterator::get_pending_events (Moment) const
+{
+  SCM s = SCM_EOL;
+  if (last_processed_mom_ < Moment (0))
+    {
+      Music_sequence * ms = dynamic_cast<Music_sequence*> (get_music ());
+     
+      for (SCM m = ms->music_list (); gh_pair_p (m); m = ly_cdr (m))
+	{
+	  s = gh_cons (ly_car (m) , s);
+	}
+    }
+  return s;
+}
+
+void
+Event_chord_iterator::process (Moment m)
+{
+  if (last_processed_mom_ < Moment (0))
+    {
+      for (SCM s = dynamic_cast<Music_sequence *> (get_music ())->music_list ();
+	   gh_pair_p (s);  s = ly_cdr (s))
+	{
+	  Music *mus = unsmob_music (ly_car (s));
+
+	  bool gotcha = try_music (mus);
+	  if (!gotcha)
+	    mus->origin ()->warning (_f ("Junking event: `%s'", classname (mus)));
+	}
+    }
+  skip (m);
+}
+
+IMPLEMENT_CTOR_CALLBACK (Event_chord_iterator);
diff --git a/lily/event.cc b/lily/event.cc
new file mode 100644
index 0000000000..11fa0ff0c5
--- /dev/null
+++ b/lily/event.cc
@@ -0,0 +1,192 @@
+/*
+  event.cc -- implement Event
+
+  source file of the GNU LilyPond music typesetter
+
+  (c) 1996--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#include "event.hh"
+#include "warn.hh"
+#include "event.hh"
+  
+Moment
+Event::get_length () const
+{
+  Duration *d = unsmob_duration (get_mus_property ("duration"));
+  if (!d)
+    {
+      Moment m ;
+      return m;
+    }
+  return d->get_length ();
+}
+
+void
+Event::compress (Moment m)
+{
+  Duration *d =  unsmob_duration (get_mus_property ("duration"));
+  if (d)
+    set_mus_property ("duration", d ->compressed (m.main_part_).smobbed_copy ());
+}
+
+void
+Event::transpose (Pitch delta)
+{
+  Pitch *p = unsmob_pitch (get_mus_property ("pitch"));
+  if (!p)
+    return ;
+
+  Pitch np = *p;
+  np.transpose (delta);
+  
+  if (abs (np.alteration_) > 2)
+    {
+	warning (_f ("Transposition by %s makes accidental larger than two",
+	  delta.string ()));
+    }
+
+  set_mus_property ("pitch", np.smobbed_copy ());
+}
+
+Pitch
+ Event::to_relative_octave (Pitch last)
+{
+  Pitch *old_pit = unsmob_pitch (get_mus_property ("pitch"));
+  if (old_pit)
+    {
+      Pitch new_pit = *old_pit;
+      new_pit.to_relative_octave (last);
+      set_mus_property ("pitch", new_pit.smobbed_copy ());
+  
+      return new_pit;
+    }
+  return last;
+}
+  
+Event::Event ()
+  : Music ()
+{
+}
+
+ADD_MUSIC(Event);
+LY_DEFINE(music_duration_length, "music-duration-length", 1, 0,0,
+	  (SCM mus),
+	  "Extract the duration field from @var{mus}, and return the length.")
+{
+  Music* m =   unsmob_music(mus);
+  SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
+  
+  Duration *d = unsmob_duration (m->get_mus_property ("duration"));
+
+  Moment l ;
+  
+  if (d)
+    {
+      l = d->get_length ();  
+    }
+  else
+    programming_error("Music has no duration");
+  return l.smobbed_copy();
+  
+}
+
+
+LY_DEFINE(music_duration_compress, "music-duration-compress", 2, 0,0,
+	  (SCM mus, SCM factor),
+	  "Extract the duration field from @var{mus}, and compress it.")
+{
+  Music* m =   unsmob_music(mus);
+  Moment * f = unsmob_moment (factor);
+  SCM_ASSERT_TYPE(m, mus, SCM_ARG1, __FUNCTION__, "Music");
+  SCM_ASSERT_TYPE(f, factor, SCM_ARG2, __FUNCTION__, "Moment");
+  
+  Duration *d = unsmob_duration (m->get_mus_property ("duration"));
+  if (d)
+    m->set_mus_property ("duration", d->compressed (f->main_part_).smobbed_copy());
+  return SCM_UNSPECIFIED;
+}
+
+
+
+/*
+  This is hairy, since the scale in a key-change event may contain
+  octaveless notes.
+ */
+LY_DEFINE(transpose_key_alist,"transpose-key-alist",
+	  2, 0,0, (SCM l, SCM pitch),
+	  "Make a new key alist of @var{l} transposed by pitch @var{pitch}")
+{
+  SCM newlist = SCM_EOL;
+  Pitch *p = unsmob_pitch (pitch);
+  
+  for (SCM s = l; gh_pair_p (s); s = ly_cdr (s))
+    {
+      SCM key = ly_caar (s);
+      SCM alter = ly_cdar (s);
+      if (gh_pair_p (key))
+	{
+	  Pitch orig (gh_scm2int (ly_car (key)),
+			      gh_scm2int (ly_cdr (key)),
+			      gh_scm2int (alter));
+
+	  orig.transpose (*p);
+
+	  SCM key = gh_cons (scm_int2num (orig.get_octave ()),
+			     scm_int2num (orig.notename_));
+
+	  newlist = gh_cons (gh_cons (key, scm_int2num (orig.alteration_)),
+			     newlist);
+	}
+      else if (gh_number_p (key))
+	{
+	  Pitch orig (0, gh_scm2int (key), gh_scm2int (alter));
+	  orig.transpose (*p);
+
+	  key =scm_int2num (orig.notename_);
+	  alter = scm_int2num (orig.alteration_);
+	  newlist = gh_cons (gh_cons (key, alter), newlist);
+	}
+    }
+  return scm_reverse_x (newlist, SCM_EOL);
+}
+
+void
+Key_change_req::transpose (Pitch p)
+{
+  SCM pa = get_mus_property ("pitch-alist");
+
+  set_mus_property ("pitch-alist", transpose_key_alist (pa, p.smobbed_copy()));
+}
+
+
+bool
+alist_equal_p (SCM a, SCM b)
+{
+  for (SCM s = a;
+       gh_pair_p (s); s = ly_cdr (s))
+    {
+      SCM key = ly_caar (s);
+      SCM val = ly_cdar (s);
+      SCM l = scm_assoc (key, b);
+
+      if (l == SCM_BOOL_F
+	  || !gh_equal_p ( ly_cdr (l), val))
+
+	return false;
+    }
+  return true;
+}
+
+bool
+Key_change_req::do_equal_b (Event const * m )const
+{
+  Key_change_req const * kc =dynamic_cast<Key_change_req const*> (m);
+
+  if(!kc)
+    return false;
+  return alist_equal_p (get_mus_property ("pitch-alist"),
+			kc->get_mus_property ("pitch-alist"));
+}
+
+ADD_MUSIC (Key_change_req);
diff --git a/lily/include/event-chord-iterator.hh b/lily/include/event-chord-iterator.hh
new file mode 100644
index 0000000000..ea9ac24b54
--- /dev/null
+++ b/lily/include/event-chord-iterator.hh
@@ -0,0 +1,45 @@
+/*
+  event-iter.hh -- declare Event_chord_iterator
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+
+#ifndef EVENT_ITER_HH
+#define EVENT_ITER_HH
+
+#include "simple-music-iterator.hh"
+
+/**
+   Walk through a Event_chord
+ */
+class Event_chord_iterator : public Simple_music_iterator
+{
+  Event_chord * get_elt () const;
+  /**
+     Find a bottom notation context to deliver events to.
+   */
+  virtual Translator_group* get_req_translator ();
+
+
+  /*
+    Since Event_chord_iterator has no list-cursor internally, we
+    must use a status variable to adminstrate where we are */
+  
+  enum { NONE_DONE, START_DONE, END_DONE }  status_;
+public:
+  VIRTUAL_COPY_CONS (Music_iterator);
+  DECLARE_SCHEME_CALLBACK(constructor, ());
+  Event_chord_iterator ();
+  Event_chord_iterator (Event_chord_iterator const&);
+
+  virtual SCM get_pending_events (Moment) const;
+protected:
+  virtual void process (Moment);
+  virtual void construct_children ();
+};
+
+
+#endif // EVENT_ITER_HH
diff --git a/lily/include/event.hh b/lily/include/event.hh
new file mode 100644
index 0000000000..0d1823c8a5
--- /dev/null
+++ b/lily/include/event.hh
@@ -0,0 +1,55 @@
+/*
+  event.hh -- declare Event baseclasses.
+
+  source file of the GNU LilyPond music typesetter
+
+  (c)  1997--2002 Han-Wen Nienhuys <hanwen@cs.uu.nl>
+*/
+
+#ifndef EVENT_HH
+#define EVENT_HH
+
+
+#include "string.hh"
+#include "moment.hh"
+#include "virtual-methods.hh"
+#include "input.hh"
+#include "music.hh"
+#include "duration.hh"
+#include "pitch.hh"
+
+/** An atom of musical information.  This is an abstract class for any
+  piece of music that does not contain other Music.
+  
+
+ */
+class Event : public Music {
+public:
+  Event ();
+  VIRTUAL_COPY_CONS (Music);
+  virtual void compress (Moment);
+  virtual void transpose (Pitch);
+  virtual Moment get_length () const;
+  virtual Pitch to_relative_octave (Pitch);
+};
+
+
+/**
+    Handle key changes.
+*/
+class Key_change_req  : public Event
+{
+public:
+  SCM pitch_alist ();
+  
+protected:
+  VIRTUAL_COPY_CONS (Music);
+  bool do_equal_b (Event const * ) const;
+  void transpose (Pitch  d);
+};
+
+SCM transpose_key_alist (SCM,SCM);
+
+
+
+#endif
diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc
index 400d1ece34..95fb3879d2 100644
--- a/lily/key-engraver.cc
+++ b/lily/key-engraver.cc
@@ -92,7 +92,7 @@ Key_engraver::try_music (Music * req)
 	  /*
 	    do this only once, just to be on the safe side.
 	    */	    
-	  keyreq_ = req;
+	  keyreq_ = dynamic_cast<Key_change_req*> (req); // UGH.
 	  read_req (keyreq_);
 	}
       
diff --git a/scm/music-types.scm b/scm/music-types.scm
index 03d2c60494..32522e672a 100644
--- a/scm/music-types.scm
+++ b/scm/music-types.scm
@@ -366,7 +366,7 @@
      . (
 	(description .  "")
 
-	(internal-class-name . "Event_chord")
+	(internal-class-name . "Simultaneous_music")
 	(iterator-ctor . ,Event_chord_iterator::constructor)
 	(types . (general-music event-chord simultaneous-music))
 	)