]> git.donarmstrong.com Git - lilypond.git/commitdiff
add
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 29 Sep 2002 17:16:18 +0000 (17:16 +0000)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 29 Sep 2002 17:16:18 +0000 (17:16 +0000)
ChangeLog
lily/context-specced-music-iterator.cc [new file with mode: 0644]
lily/event-chord-iterator.cc [new file with mode: 0644]
lily/event.cc [new file with mode: 0644]
lily/include/event-chord-iterator.hh [new file with mode: 0644]
lily/include/event.hh [new file with mode: 0644]
lily/key-engraver.cc
scm/music-types.scm

index 58f40e2a7be4ea3f6ac383eebb2ca5723bebec64..36bf7a0cbf78470b63ec0056ed0ca10fbea2cedc 100644 (file)
--- 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 (file)
index 0000000..1fab03f
--- /dev/null
@@ -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 (file)
index 0000000..ea9636d
--- /dev/null
@@ -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 (file)
index 0000000..11fa0ff
--- /dev/null
@@ -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 (file)
index 0000000..ea9ac24
--- /dev/null
@@ -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 (file)
index 0000000..0d1823c
--- /dev/null
@@ -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
index 400d1ece34cb7e420e78024cd789a82b73151da5..95fb3879d2a0ed56ee62e192d7c08c0332dcf2b4 100644 (file)
@@ -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_);
        }
       
index 03d2c604940843790fd319dcb6452f6aedb42dbf..32522e672a06c1c1e5093ee44f9f5257236da384 100644 (file)
      . (
        (description .  "")
 
-       (internal-class-name . "Event_chord")
+       (internal-class-name . "Simultaneous_music")
        (iterator-ctor . ,Event_chord_iterator::constructor)
        (types . (general-music event-chord simultaneous-music))
        )