From: Han-Wen Nienhuys Date: Thu, 21 Jul 2005 12:14:35 +0000 (+0000) Subject: *** empty log message *** X-Git-Tag: release/2.7.3~28 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=561e465038d7ee45d892fcd3f1f0821fff0b0156;p=lilypond.git *** empty log message *** --- diff --git a/ChangeLog b/ChangeLog index ae9e071d09..44198d866b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -7,6 +7,17 @@ 2005-07-21 Han-Wen Nienhuys + * Documentation/topdocs/NEWS.tely (Top): add note about Musica ficta. + + * Documentation/user/instrument-notation.itely (Musica ficta + accidentals): add section Musica ficta accidentals + + * lily/accidental-engraver.cc (make_suggested_accidental): new function. + (make_standard_accidental): move into new function. + (create_accidental): new function. + + * scm/define-grobs.scm (all-grob-descriptions): new Grob AccidentalSuggestion + * lily/output-def-scheme.cc (LY_DEFINE): take default argument. * lily/output-def.cc (lookup_variable): return SCM_UNDEFINED if undefined. diff --git a/Documentation/topdocs/NEWS.tely b/Documentation/topdocs/NEWS.tely index 37dce23a07..213ae0ff3b 100644 --- a/Documentation/topdocs/NEWS.tely +++ b/Documentation/topdocs/NEWS.tely @@ -32,6 +32,18 @@ See user manual, \NAME\ @itemize @bullet + +@item +Suggested accidentals (for notating musica ficta) may be switched on +with @code{suggestAccidentals} + +@lilypond[verbatim,fragment,relative=2] +\set suggestAccidentals = ##t +ais bis +@end lilypond + +This feature was sponsored by Nancho Alvarez. + @item The setting @code{whichBar} and time-bookkeeping is now split into a @code{Default_bar_line_engraver} and @code{Timing_translator} diff --git a/Documentation/user/instrument-notation.itely b/Documentation/user/instrument-notation.itely index c20b3bf9d1..5c65a24b00 100644 --- a/Documentation/user/instrument-notation.itely +++ b/Documentation/user/instrument-notation.itely @@ -1940,10 +1940,12 @@ Here are all suptopics at a glance: * Ligatures:: * Gregorian Chant contexts:: * Mensural contexts:: +* Musica ficta accidentals:: * Figured bass:: @end menu + @node Ancient note heads @subsection Ancient note heads @@ -3771,6 +3773,31 @@ entering the chant, as the following excerpt demonstrates } @end lilypond +@node Musica ficta accidentals +@subsection Musica ficta accidentals + +In European music from before about 1600, singers were often expected +to chromatically alter notes at their own initiative. This is called +``Musica Ficta''. In modern transcriptions, these accidentals are +usually printed over the note. + +@cindex Musica ficta + +Support for such suggested accidentals is included, and can be +switched on by setting @code{suggestAccidentals} to true. + +@cindex @code{suggestAccidentals} + +@lilypond[verbatim,fragment,relative=1] +fis gis +\set suggestAccidentals = ##t +ais bis +@end lilypond + +@seealso + +Program reference: @internalsref{Accidental_engraver} engraver and the +@internalsref{AccidentalSuggestion} object. @node Figured bass @subsection Figured bass diff --git a/THANKS b/THANKS index bed0d62e20..0b3427c618 100644 --- a/THANKS +++ b/THANKS @@ -21,6 +21,7 @@ SPONSORS Jamie Bullock D. Josiah Boothby +Nancho Alvarez Sven Axelsson diff --git a/input/regression/accidental-suggestions.ly b/input/regression/accidental-suggestions.ly new file mode 100644 index 0000000000..d160ed01e9 --- /dev/null +++ b/input/regression/accidental-suggestions.ly @@ -0,0 +1,26 @@ + +\header { + + texidoc = "setting the @code{suggestAccidentals} will print +accidentals vertically relative to the note. This is useful for +denoting Musica Ficta." + +} + +\version "2.7.2" +\paper { + raggedright = ##t +} + +\relative c'' { + \time 2/4 + \set suggestAccidentals = ##t + cis^> gis'-| + \override AccidentalSuggestion #'cautionary-style = #'parentheses + cis,_"paren" gis' + \override AccidentalSuggestion #'cautionary-style = #'() + cis,_"no caut style" gis' + +} + + diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index 6898520441..2b6c3741d3 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -28,7 +28,7 @@ public: Music *melodic_; Grob *accidental_; Context *origin_; - Engraver *origin_trans_; + Engraver *origin_engraver_; Grob *head_; bool tied_; @@ -47,10 +47,12 @@ Accidental_entry::Accidental_entry () class Accidental_engraver : public Engraver { -public: int get_bar_number (); void update_local_key_signature (); - + void create_accidental (Accidental_entry *entry, bool, bool); + Grob *make_standard_accidental (Music *note, Grob *note_head, Engraver *trans); + Grob *make_suggested_accidental (Music *note, Grob *note_head, Engraver *trans); + protected: TRANSLATOR_DECLARATIONS (Accidental_engraver); PRECOMPUTED_VIRTUAL void process_music (); @@ -59,14 +61,16 @@ protected: virtual void initialize (); PRECOMPUTED_VIRTUAL void process_acknowledged (); virtual void finalize (); - virtual void derived_mark () const; + public: SCM last_keysig_; // ugh. - /* Urgh. Since the accidentals depend on lots of variables, we have - to store all information before we can really create the - accidentals. */ + /* + Urgh. Since the accidentals depend on lots of variables, we have + to store all information before we can really create the + accidentals. + */ Link_array left_objects_; Link_array right_objects_; @@ -74,6 +78,8 @@ public: Array accidentals_; Link_array ties_; + + }; /* @@ -311,13 +317,12 @@ Accidental_engraver::process_acknowledged () SCM cautionaries = get_property ("autoCautionaries"); int barnum = get_bar_number (); - bool extra_natural_b = get_property ("extraNatural") == SCM_BOOL_T; for (int i = 0; i < accidentals_.size (); i++) { if (accidentals_[i].done_) continue; accidentals_[i].done_ = true; - Grob *support = accidentals_[i].head_; + Music *note = accidentals_[i].melodic_; Context *origin = accidentals_[i].origin_; @@ -351,50 +356,108 @@ Accidental_engraver::process_acknowledged () us before the notes. */ if (num) { - /* - We construct the accidentals at the originating Voice - level, so that we get the property settings for - Accidental from the respective Voice. - */ - Grob *a - = make_item_from_properties (accidentals_[i].origin_trans_, - ly_symbol2scm ("Accidental"), - note->self_scm (), - "Accidental"); - a->set_parent (support, Y_AXIS); + create_accidental (&accidentals_[i], num > 1, cautionary); + } + } + } +} - if (!accidental_placement_) - accidental_placement_ = make_item ("AccidentalPlacement", - a->self_scm ()); - Accidental_placement::add_accidental (accidental_placement_, a); - SCM accs = scm_cons (scm_int2num (pitch->get_alteration ()), - SCM_EOL); - if (num == 2 && extra_natural_b) - accs = scm_cons (scm_int2num (0), accs); +void +Accidental_engraver::create_accidental (Accidental_entry *entry, + bool restore_natural, + bool cautionary) +{ + Music *note = entry->melodic_; + Grob *support = entry->head_; + Pitch *pitch = unsmob_pitch (note->get_property ("pitch")); + + + bool as_suggestion = get_property ("suggestAccidentals"); + Grob *a = 0; + if (as_suggestion) + a = make_suggested_accidental (note, support, entry->origin_engraver_); + else + a = make_standard_accidental (note, support, entry->origin_engraver_); + + SCM accs = scm_cons (scm_int2num (pitch->get_alteration ()), + SCM_EOL); + if (restore_natural) + { + if (to_boolean (get_property ("extraNatural"))) + accs = scm_cons (scm_int2num (0), accs); + } + + /* TODO: add cautionary option in accidental. */ + if (cautionary) + a->set_property ("cautionary", SCM_BOOL_T); - /* TODO: add cautionary option in accidental. */ - if (cautionary) - a->set_property ("cautionary", SCM_BOOL_T); + a->set_property ("accidentals", accs); + entry->accidental_ = a; +} - support->set_object ("accidental-grob", a->self_scm ()); +Grob * +Accidental_engraver::make_standard_accidental (Music *note, + Grob *support, + Engraver *trans) +{ + + /* + We construct the accidentals at the originating Voice + level, so that we get the property settings for + Accidental from the respective Voice. + */ + Grob *a + = make_grob_from_properties (trans, + ly_symbol2scm ("Accidental"), + note->self_scm (), + "Accidental"); + + /* + We add the accidentals to the support of the arpeggio, + so it is put left of the accidentals. + */ + for (int i = 0; i < left_objects_.size (); i++) + Side_position_interface::add_support (left_objects_[i], a); + for (int i = 0; i < right_objects_.size (); i++) + Side_position_interface::add_support (a, right_objects_[i]); + + a->set_parent (support, Y_AXIS); + + if (!accidental_placement_) + accidental_placement_ = make_item ("AccidentalPlacement", + a->self_scm ()); + Accidental_placement::add_accidental (accidental_placement_, a); + + support->set_object ("accidental-grob", a->self_scm ()); + + return a; +} - a->set_property ("accidentals", accs); - accidentals_[i].accidental_ = a; - /* - We add the accidentals to the support of the arpeggio, - so it is put left of the accidentals. - */ - for (int i = 0; i < left_objects_.size (); i++) - Side_position_interface::add_support (left_objects_[i], a); - for (int i = 0; i < right_objects_.size (); i++) - Side_position_interface::add_support (a, right_objects_[i]); - } - } +Grob * +Accidental_engraver::make_suggested_accidental (Music *note, + Grob *note_head, Engraver *trans) +{ + + Grob *a + = make_grob_from_properties (trans, + ly_symbol2scm ("AccidentalSuggestion"), + note->self_scm (), + "AccidentalSuggestion"); + + + Side_position_interface::add_support (a, note_head); + if (Grob *stem = unsmob_grob (a->get_object ("stem"))) + { + Side_position_interface::add_support (a, stem); } + + a->set_parent (note_head, X_AXIS); + return a; } + void Accidental_engraver::finalize () { @@ -489,14 +552,17 @@ Accidental_engraver::acknowledge_grob (Grob_info info) && note->is_mus_type ("note-event") && Rhythmic_head::has_interface (info.grob ())) { + /* + String harmonics usually don't have accidentals. + */ if (to_boolean (get_property ("harmonicAccidentals")) || !ly_is_equal (info.grob ()->get_property ("style"), ly_symbol2scm ("harmonic"))) { Accidental_entry entry; entry.head_ = info.grob (); - entry.origin_trans_ = dynamic_cast (info.origin_translator ()); - entry.origin_ = entry.origin_trans_->context (); + entry.origin_engraver_ = dynamic_cast (info.origin_translator ()); + entry.origin_ = entry.origin_engraver_->context (); entry.melodic_ = note; accidentals_.push (entry); @@ -527,12 +593,16 @@ ADD_TRANSLATOR (Accidental_engraver, "This engraver usually lives at Staff level, but " "reads the settings for Accidental at @code{Voice} level, " "so you can @code{\\override} them at @code{Voice}. ", - "Accidental", + "Accidental AccidentalSuggestion", + "", + + /* acks */ "arpeggio-interface " "finger-interface " "rhythmic-head-interface " "tie-interface ", + "autoAccidentals " "autoCautionaries " "extraNatural " diff --git a/lily/engraver.cc b/lily/engraver.cc index b1a11fcd3a..a93b202cbc 100644 --- a/lily/engraver.cc +++ b/lily/engraver.cc @@ -59,7 +59,11 @@ Engraver::get_score_engraver () const #include "translator.icc" ADD_TRANSLATOR (Engraver, - "", "", + "Base class for engravers. Does nothing, so it is not used.", "", - "", "", ""); + "", + "", + "", + ""); + diff --git a/lily/include/engraver.hh b/lily/include/engraver.hh index 54e4f28776..56a2fe44eb 100644 --- a/lily/include/engraver.hh +++ b/lily/include/engraver.hh @@ -48,6 +48,7 @@ public: #define make_item(x, cause) make_item_from_properties (this, ly_symbol2scm (x), cause, x) #define make_spanner(x, cause) make_spanner_from_properties (this, ly_symbol2scm (x), cause, x) #define make_paper_column(x) make_paper_column_from_properties (this, ly_symbol2scm (x), x) +Grob *make_grob_from_properties (Engraver *tr, SCM symbol, SCM cause, const char *name); Item *make_item_from_properties (Engraver *tg, SCM x, SCM cause, const char *name); Spanner *make_spanner_from_properties (Engraver *tg, SCM x, SCM cause, const char *name); Paper_column *make_paper_column_from_properties (Engraver *tg, SCM x, const char *name); diff --git a/scm/define-context-properties.scm b/scm/define-context-properties.scm index 6cf862af69..d01608205f 100644 --- a/scm/define-context-properties.scm +++ b/scm/define-context-properties.scm @@ -354,6 +354,7 @@ one).") (subdivideBeams ,boolean? "If set, multiple beams will be subdivided at beat positions by only drawing one beam over the beat.") + (suggestAccidentals ,boolean? "If set, accidentals are typeset as cautionary suggestions over the note.") (systemStartDelimiter ,symbol? "Which grob to make for the start of the system/staff? Set to @code{SystemStartBrace}, diff --git a/scm/define-grob-interfaces.scm b/scm/define-grob-interfaces.scm index ffad4afbc1..65e4bb859e 100644 --- a/scm/define-grob-interfaces.scm +++ b/scm/define-grob-interfaces.scm @@ -16,6 +16,12 @@ '(accidental-grob) ) +(ly:add-interface + 'accidental-suggestion-interface + "An accidental, printed as a suggestion (typically: vertically over a note)" + '() + ) + (ly:add-interface 'dynamic-interface "Any kind of loudness sign" diff --git a/scm/define-grobs.scm b/scm/define-grobs.scm index b8024dddcb..33e83c8d76 100644 --- a/scm/define-grobs.scm +++ b/scm/define-grobs.scm @@ -24,10 +24,26 @@ (cautionary-style . parentheses) (after-line-breaking-callback . ,Accidental_interface::after_line_breaking) (meta . ((class . Item) - (interfaces . (accidental-interface - font-interface)))) + (interfaces . (accidental-interface font-interface)))) + )) + + (AccidentalSuggestion + . ((print-function . ,Accidental_interface::print) + (X-offset-callbacks . (,Self_alignment_interface::centered_on_parent + ,Self_alignment_interface::aligned_on_self)) + (self-alignment-X . ,CENTER) + (cautionary . #t) + (cautionary-style . smaller) + (Y-offset-callbacks . (,Side_position_interface::aligned_side)) + (cautionary-style . parentheses) + (direction . ,UP) + (staff-padding . 0.25) + (script-priority . 0) + (meta . ((class . Item) + (interfaces . (side-position-interface script-interface + accidental-suggestion-interface self-alignment-interface + font-interface)))) )) - (AccidentalPlacement . ((X-extent-callback . ,Axis_group_interface::group_extent_callback) (left-padding . 0.2) @@ -865,7 +881,8 @@ (staff-padding . 0.2) (font-size . -4) (meta . ((class . Item) - (interfaces . (text-interface self-alignment-interface side-position-interface font-interface )))) + (interfaces . (text-interface self-alignment-interface + side-position-interface font-interface )))) )) (OttavaBracket