+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>
--- /dev/null
+/*
+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);
--- /dev/null
+/*
+ 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);
--- /dev/null
+/*
+ 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);
--- /dev/null
+/*
+ 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
--- /dev/null
+/*
+ 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
/*
do this only once, just to be on the safe side.
*/
- keyreq_ = req;
+ keyreq_ = dynamic_cast<Key_change_req*> (req); // UGH.
read_req (keyreq_);
}
. (
(description . "")
- (internal-class-name . "Event_chord")
+ (internal-class-name . "Simultaneous_music")
(iterator-ctor . ,Event_chord_iterator::constructor)
(types . (general-music event-chord simultaneous-music))
)