From: Jan Nieuwenhuizen Date: Thu, 9 Mar 2000 13:27:13 +0000 (+0100) Subject: patch::: 1.3.31.jcn1 X-Git-Tag: release/1.3.32~2 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=f5cd261f30895d55144216ff4c134bf19126332b;p=lilypond.git patch::: 1.3.31.jcn1 1.3.30.jcn4 =========== * Adjacent dynamic markings are now grouped on a horizontal line, but it's not perfect yet: they're always below the staff and no horizontal spacing is done. Also, character metrics of dynamics are still not used. See: input/test/crescendi.ly and input/test/dyn-line.ly * Cleaned up Span_dynamic_performer. --- diff --git a/CHANGES b/CHANGES index 9e57175791..4b8dcfb1ea 100644 --- a/CHANGES +++ b/CHANGES @@ -1,3 +1,13 @@ +1.3.30.jcn4 +=========== + +* Adjacent dynamic markings are now grouped on a horizontal line, but it's + not perfect yet: they're always below the staff and no horizontal spacing + is done. Also, character metrics of dynamics are still not used. + See: input/test/crescendi.ly and input/test/dyn-line.ly + +* Cleaned up Span_dynamic_performer. + 1.3.30.mb1 ========= @@ -8,19 +18,20 @@ 1.3.30.jcn3 =========== -* Span_dynamic_performer; perform crescendi/decrescendi. Bit scrappy. +* Lily now also performs crescendi and decrescendi in MIDI output: + Span_dynamic_performer (bit scrappy). -* Preliminary support for crescendi/decrescendi other than `hairpins', eg: - `cresc. poco `a poco -- -- --' +* Added preliminary support for crescendi/decrescendi other than `hairpins', + eg: `cresc. poco `a poco -- -- --' -* Tie performance fix. +* Made MIDI tie performance fix. 1.3.30.jcn2 =========== -* Dynamic_performer: performs absolute dynamic requests. +* Lily now performs absolute dynamics in MIDI output. -* David's comments on opus47 +* Included David's comments on opus47 in TODO. 1.3.30.jcn1 =========== diff --git a/VERSION b/VERSION index 023bbc67de..103c9b2621 100644 --- a/VERSION +++ b/VERSION @@ -2,7 +2,7 @@ PACKAGE_NAME=LilyPond MAJOR_VERSION=1 MINOR_VERSION=3 PATCH_LEVEL=31 -MY_PATCH_LEVEL= +MY_PATCH_LEVEL=jcn1 # use the above to send patches: MY_PATCH_LEVEL is always empty for a # released version. diff --git a/input/test/crescendi.ly b/input/test/crescendi.ly index 3d47741875..0175ce9ccc 100644 --- a/input/test/crescendi.ly +++ b/input/test/crescendi.ly @@ -1,13 +1,11 @@ \score{ \notes\relative c''{ -a1\fff\< \!a -a\> \!a +a1\fff\> \!a\pp +a\< \!a \property Voice.crescendoText = "cresc." \property Voice.crescendoSpanner = "dashed-line" a\mf\cresc \endcresc a -%a\decresc \enddecresc a -a1\< \!a -a\> \!a +a\< \!a } \paper{ } diff --git a/input/test/dyn-line.ly b/input/test/dyn-line.ly new file mode 100644 index 0000000000..38f023b5b9 --- /dev/null +++ b/input/test/dyn-line.ly @@ -0,0 +1,19 @@ +\score{ +\notes\relative c''{ +a1\fff\> \!c,,\pp a'' a\p + + +% We need this to test if we get two Dynamic line spanners +a + +% because Dynamic_engraver::do_removal_processing () +% doesn't seem to do its job? +a\f + +} +\paper{ +} +\midi{ +\tempo 1 = 60; +} +} diff --git a/input/test/span-dynamic.ly b/input/test/span-dynamic.ly index 8c48f7d3a0..e69de29bb2 100644 --- a/input/test/span-dynamic.ly +++ b/input/test/span-dynamic.ly @@ -1,17 +0,0 @@ -\score{ -\notes\relative c''{ -a1\ppp\< -a -a -a -a -a -a -\!a\fff -} -\paper{ -} -\midi{ -\tempo 1 = 60; -} -} diff --git a/lily/dynamic-engraver.cc b/lily/dynamic-engraver.cc index 254271080f..c1d9172879 100644 --- a/lily/dynamic-engraver.cc +++ b/lily/dynamic-engraver.cc @@ -1,11 +1,12 @@ /* - dynamic-reg.cc -- implement Dynamic_engraver + dynamic-engraver.cc -- implement Dynamic_engraver source file of the GNU LilyPond music typesetter (c) 1997--2000 Han-Wen Nienhuys */ #include "debug.hh" +#include "dimensions.hh" #include "crescendo.hh" #include "musical-request.hh" #include "lookup.hh" @@ -19,6 +20,148 @@ #include "stem.hh" #include "note-head.hh" #include "group-interface.hh" +#include "directional-element-interface.hh" +#include "staff-symbol-referencer.hh" + +#define DYN_LINE + +#ifdef DYN_LINE + +class Dynamic_line_spanner : public Spanner +{ +public: + Dynamic_line_spanner (); + + void add_element (Score_element*); + void add_column (Note_column*); + Direction get_default_dir () const; + +protected: + virtual void do_add_processing (); + // URG: see Dynamic_engraver::do_removal_processing + friend class Dynamic_engraver; + virtual void do_post_processing (); + +private: + void translate_elements (Real); + Real get_extreme_y () const; +}; + +Dynamic_line_spanner::Dynamic_line_spanner () +{ + set_elt_property ("transparent", SCM_BOOL_T); +} + +void +Dynamic_line_spanner::add_element (Score_element* e) +{ + Group_interface gi (this, "elements"); + gi.add_element (e); + //? + Side_position_interface (e).set_axis (Y_AXIS); + add_dependency (e); +} + +void +Dynamic_line_spanner::add_column (Note_column* n) +{ + Group_interface gi (this, "note-columns"); + gi.add_element (n); + add_dependency (n); +} + +/* + Copied (urg: literally!) from slur. + Why not do this once, at post-processing stage? + */ +void +Dynamic_line_spanner::do_add_processing () +{ + Link_array encompass_arr = + Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + + if (encompass_arr.size ()) + { + set_bounds (LEFT, encompass_arr[0]); + if (encompass_arr.size () > 1) + set_bounds (RIGHT, encompass_arr.top ()); + } +} + +#if 0 +Molecule +Dynamic_line_spanner::do_brew_molecule () const +{ + return Molecule (); +} +#endif + +void +Dynamic_line_spanner::do_post_processing () +{ + translate_elements (get_extreme_y ()); +} + +void +Dynamic_line_spanner::translate_elements (Real dy) +{ + SCM s = get_elt_property ("elements"); + for (; gh_pair_p (s); s = gh_cdr (s)) + { + Score_element* se = unsmob_element (gh_car (s)); + se->translate_axis (dy, Y_AXIS); + } +} + +Direction +Dynamic_line_spanner::get_default_dir () const +{ + return DOWN; + //Direction dir = directional_element (this).get (); +} + +Real +Dynamic_line_spanner::get_extreme_y () const +{ + Link_array encompass_arr = + Group_interface__extract_elements (this, (Note_column*)0, "note-columns"); + + Staff_symbol_referencer_interface si (this); + int stafflines = si.line_count (); + //hurg? + stafflines = stafflines != 0 ? stafflines : 5; + Direction dir = get_default_dir (); + + Real staff_space = si.staff_space (); + // burp? when are these available? + staff_space = staff_space != 0 ? staff_space : 5 PT; + + // urg: TODO: padding + Real y = (stafflines / 2 + 1) * staff_space; + + for (int i = 0; i < encompass_arr.size (); i++) + { + Note_column* column = encompass_arr[i]; + Stem* stem = column->stem_l (); + if (stem) + { + Direction stem_dir = directional_element (stem).get (); + if ((stem_dir == dir) + && !stem->extent (Y_AXIS).empty_b ()) + { + y = y >? (stem->extent (Y_AXIS)[dir]) * dir; + } + else + { + y = y >? (column->extent (Y_AXIS)[dir]) * dir; + } + } + } + + return y * dir; +} + +#endif /* TODO: @@ -43,6 +186,15 @@ class Dynamic_engraver : public Engraver Span_req * cresc_req_l_; Array dynamic_req_l_arr_; + +#ifdef DYN_LINE + /* + We probably need two of these: line-up above and below staff + */ + Dynamic_line_spanner* spanner_; + Moment last_request_mom_; +#endif + void typeset_all (); public: VIRTUAL_COPY_CONS(Translator); @@ -61,6 +213,8 @@ protected: virtual void typeset_element (Score_element*); }; +ADD_THIS_TRANSLATOR (Dynamic_engraver); + void Dynamic_engraver::announce_element (Score_element_info i) { @@ -70,13 +224,16 @@ Dynamic_engraver::announce_element (Score_element_info i) } -Dynamic_engraver::Dynamic_engraver() +Dynamic_engraver::Dynamic_engraver () { do_post_move_processing(); abs_text_p_ = 0; cr_text_p_ = 0; to_end_cresc_p_ = cresc_p_ = 0; cresc_req_l_ = 0; +#ifdef DYN_LINE + spanner_ = 0; +#endif } void @@ -85,6 +242,9 @@ Dynamic_engraver::do_post_move_processing() dynamic_req_l_arr_.clear(); } +/* + ugr + */ bool Dynamic_engraver::do_try_music (Music * m) { @@ -104,6 +264,12 @@ Dynamic_engraver::do_try_music (Music * m) else return false; +#ifdef DYN_LINE + if (!spanner_) + spanner_ = new Dynamic_line_spanner; + last_request_mom_ = now_mom (); +#endif + for (int i=0; i < dynamic_req_l_arr_.size (); i++) if (r->equal_b (dynamic_req_l_arr_[i])) return true; @@ -138,8 +304,11 @@ Dynamic_engraver::do_process_requests() abs_text_p_->set_elt_property ("script-priority", gh_int2scm (100)); +#ifdef DYN_LINE + assert (spanner_); + spanner_->add_element (abs_text_p_); +#else Side_position_interface (abs_text_p_).set_axis (Y_AXIS); - if (absd->get_direction ()) { @@ -164,7 +333,9 @@ Dynamic_engraver::do_process_requests() { abs_text_p_->set_elt_property ("padding", prop); } +#endif announce_element (Score_element_info (abs_text_p_, absd)); + } else if (Span_req *span_l = dynamic_cast (dynamic_req_l_arr_[i])) @@ -222,6 +393,12 @@ Dynamic_engraver::do_process_requests() Side_position_interface (cr_text_p_).set_axis (X_AXIS); Side_position_interface (cr_text_p_).add_support (abs_text_p_); } + +#ifdef DYN_LINE + assert (spanner_); + spanner_->add_element (cr_text_p_); +#endif + //Side_position_interface (cr_text_p_).set_axis (Y_AXIS); announce_element (Score_element_info (cr_text_p_, span_l)); } @@ -232,7 +409,13 @@ Dynamic_engraver::do_process_requests() new_cresc_p->set_elt_property ("spanner", s); } +#ifdef DYN_LINE + assert (spanner_); + spanner_->add_element (new_cresc_p); +#else + // what's the diff between side_position and Side_pos_iface? side_position (new_cresc_p).set_axis (Y_AXIS); +#endif announce_element (Score_element_info (new_cresc_p, span_l)); } } @@ -262,6 +445,7 @@ Dynamic_engraver::do_process_requests() RIGHT, SCM_BOOL_T); } } + } void @@ -270,10 +454,6 @@ Dynamic_engraver::do_pre_move_processing() typeset_all (); } - - -ADD_THIS_TRANSLATOR(Dynamic_engraver); - void Dynamic_engraver::do_removal_processing () { @@ -283,6 +463,15 @@ Dynamic_engraver::do_removal_processing () cresc_req_l_->warning (_ ("unended crescendo")); cresc_p_ =0; } +#ifdef DYN_LINE + if (spanner_) + { + // URG urg. We did't get a post_processing call !? + spanner_->do_post_processing (); + typeset_element (spanner_); + spanner_ = 0; + } +#endif typeset_all (); } @@ -310,15 +499,44 @@ Dynamic_engraver::typeset_all () typeset_element (cr_text_p_); cr_text_p_ = 0; } +#ifdef DYN_LINE + /* + TODO: This should be optionised: + * break when group of dynamic requests ends + * break now + * continue through piece + */ + if (spanner_ && last_request_mom_ < now_mom ()) + { + typeset_element (spanner_); + spanner_ = 0; + } +#endif } void Dynamic_engraver::typeset_element (Score_element * e) { +#ifndef DYN_LINE side_position(e).add_staff_support (); +#endif Engraver::typeset_element (e); } +#ifdef DYN_LINE + +void +Dynamic_engraver::acknowledge_element (Score_element_info i) +{ + if (spanner_) + { + if (Note_column* n = dynamic_cast (i.elem_l_)) + spanner_->add_column (n); + } +} + +#else + void Dynamic_engraver::acknowledge_element (Score_element_info i) { @@ -343,3 +561,4 @@ Dynamic_engraver::acknowledge_element (Score_element_info i) } } +#endif diff --git a/lily/rest-collision.cc b/lily/rest-collision.cc index 6bdfe4eaf2..07ab3c764a 100644 --- a/lily/rest-collision.cc +++ b/lily/rest-collision.cc @@ -17,6 +17,7 @@ #include "paper-def.hh" #include "rest.hh" #include "group-interface.hh" +#include "staff-symbol-referencer.hh" void Rest_collision::add_column (Note_column *nc_l) @@ -115,8 +116,10 @@ Rest_collision::do_pre_processing() // FIXME - int stafflines = 5; // rcol->rest_l_arr[0]->line_count; - + //int stafflines = 5; // rcol->rest_l_arr[0]->line_count; + int stafflines = Staff_symbol_referencer_interface (this).line_count (); + // hurg? + stafflines = stafflines != 0 ? stafflines : 5; // move discretely by half spaces. int discrete_dist = int (ceil (dist / (0.5 *staff_space))); diff --git a/lily/span-dynamic-performer.cc b/lily/span-dynamic-performer.cc index c6f115901a..415852f573 100644 --- a/lily/span-dynamic-performer.cc +++ b/lily/span-dynamic-performer.cc @@ -18,7 +18,7 @@ struct Audio_dynamic_tuple }; /** - handle perform span-dynamics + perform span-dynamics */ class Span_dynamic_performer : public Performer { @@ -34,17 +34,11 @@ protected: virtual void do_pre_move_processing (); private: + Audio_dynamic* audio_p_; Drul_array request_drul_; - Drul_array moment_drul_; - Drul_array volume_drul_; Array dynamic_tuple_arr_; - - // BURP - Drul_array done_moment_drul_; - Drul_array done_volume_drul_; - Array done_dynamic_tuple_arr_; - - Audio_dynamic* audio_p_; + Array finished_dynamic_tuple_arr_; + Direction finished_dir_; }; ADD_THIS_TRANSLATOR (Span_dynamic_performer); @@ -52,7 +46,6 @@ ADD_THIS_TRANSLATOR (Span_dynamic_performer); Span_dynamic_performer::Span_dynamic_performer () { request_drul_[START] = request_drul_[STOP] = 0; - volume_drul_[START] = volume_drul_[STOP] = 0; audio_p_ = 0; } @@ -61,59 +54,64 @@ Span_dynamic_performer::acknowledge_element (Audio_element_info i) { if (Audio_dynamic * d = dynamic_cast (i.elem_l_)) { - Direction dir = volume_drul_[START] ? STOP : START; - volume_drul_[dir] = d->volume_i_; - if (done_dynamic_tuple_arr_.size ()) - done_volume_drul_[STOP] = d->volume_i_; -#if 0 Audio_dynamic_tuple a = { d, now_mom () }; + if (!request_drul_[START]) + dynamic_tuple_arr_.clear (); dynamic_tuple_arr_.push (a); -#endif + if (finished_dynamic_tuple_arr_.size ()) + finished_dynamic_tuple_arr_.push (a); } } void Span_dynamic_performer::do_process_requests () { - if (request_drul_[START]) - { - audio_p_ = new Audio_dynamic (volume_drul_[START]); - Audio_element_info info (audio_p_, 0); - announce_element (info); - - Audio_dynamic_tuple a = { audio_p_, now_mom () }; - dynamic_tuple_arr_.push (a); - } - - if (done_dynamic_tuple_arr_.size ()) + if (finished_dynamic_tuple_arr_.size () > 1 + && finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_) { - if (done_volume_drul_[STOP]) + Real start_volume = finished_dynamic_tuple_arr_[0].audio_l_->volume_i_; + Real dv = finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_ + - start_volume; + if (!dv) + { + // urg. about one volume step + dv = (int)finished_dir_ * 13; + if (!start_volume) + start_volume = finished_dynamic_tuple_arr_.top + ().audio_l_->volume_i_ - dv; + } + Moment start_mom = finished_dynamic_tuple_arr_[0].mom_; + Moment dt = finished_dynamic_tuple_arr_.top ().mom_ - start_mom; + for (int i=0; i < finished_dynamic_tuple_arr_.size (); i++) { - Real dv = done_volume_drul_[STOP] - done_volume_drul_[START]; - Moment dt = done_moment_drul_[STOP] - done_moment_drul_[START]; - for (int i=0; i < done_dynamic_tuple_arr_.size (); i++) - { - Real volume = - (done_volume_drul_[START] - + dv * (Real)(done_dynamic_tuple_arr_[i].mom_ - - done_moment_drul_[START]) / (Real)dt); - done_dynamic_tuple_arr_[i].audio_l_->volume_i_ = (int)volume; - } + Audio_dynamic_tuple* a = &finished_dynamic_tuple_arr_[i]; + Real volume = start_volume + dv * (Real)(a->mom_ - start_mom) + / (Real)dt; + a->audio_l_->volume_i_ = (int)volume; } - done_dynamic_tuple_arr_.clear (); + finished_dynamic_tuple_arr_.clear (); } if (request_drul_[STOP]) { - done_dynamic_tuple_arr_ = dynamic_tuple_arr_; + finished_dynamic_tuple_arr_ = dynamic_tuple_arr_; + finished_dir_ = request_drul_[STOP]->span_type_str_ == "crescendo" + ? RIGHT : LEFT; dynamic_tuple_arr_.clear (); - done_volume_drul_[START] = volume_drul_[START]; - done_volume_drul_[STOP] = volume_drul_[STOP]; - done_moment_drul_[START] = moment_drul_[START]; - done_moment_drul_[STOP] = moment_drul_[STOP]; + if (finished_dynamic_tuple_arr_.size ()) + dynamic_tuple_arr_.push (finished_dynamic_tuple_arr_.top ()); request_drul_[STOP] = 0; - volume_drul_[START] = volume_drul_[STOP]; - volume_drul_[STOP] = 0; + request_drul_[START] = 0; + } + + if (request_drul_[START]) + { + audio_p_ = new Audio_dynamic (0); + Audio_element_info info (audio_p_, 0); + announce_element (info); + + Audio_dynamic_tuple a = { audio_p_, now_mom () }; + dynamic_tuple_arr_.push (a); } } @@ -144,9 +142,6 @@ Span_dynamic_performer::do_try_music (Music* r) return false; } request_drul_[d] = s; - moment_drul_[d] = now_mom (); - if (d == START && volume_drul_[STOP]) - volume_drul_[START] = volume_drul_[STOP]; return true; } return false;