From d565eec0e4b9ecbfef333802a28435b1f54e8257 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 29 Sep 2002 17:16:18 +0000 Subject: [PATCH] add --- ChangeLog | 6 + lily/context-specced-music-iterator.cc | 41 ++++++ lily/event-chord-iterator.cc | 82 +++++++++++ lily/event.cc | 192 +++++++++++++++++++++++++ lily/include/event-chord-iterator.hh | 45 ++++++ lily/include/event.hh | 55 +++++++ lily/key-engraver.cc | 2 +- scm/music-types.scm | 2 +- 8 files changed, 423 insertions(+), 2 deletions(-) create mode 100644 lily/context-specced-music-iterator.cc create mode 100644 lily/event-chord-iterator.cc create mode 100644 lily/event.cc create mode 100644 lily/include/event-chord-iterator.hh create mode 100644 lily/include/event.hh diff --git a/ChangeLog b/ChangeLog index 58f40e2a7b..36bf7a0cbf 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2002-09-29 Han-Wen Nienhuys + + * 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 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 + + */ + +#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 +*/ + +#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 (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 (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 +*/ + +#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 (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 +*/ + + +#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 +*/ + +#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 (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)) ) -- 2.39.5