From 27e2316075225051985316e8132411961fe3e533 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Thu, 21 Sep 2006 00:19:06 +0000 Subject: [PATCH] * lily/accidental-placement.cc (calc_positioning_done): don't trigger Y-extent calculation too early. Use pure_height instead. * lily/scale.cc (LY_DEFINE): new file. --- ChangeLog | 7 +++ lily/accidental-placement.cc | 27 ++++++--- lily/include/pitch.hh | 15 ++++- lily/pitch.cc | 34 ++++++----- lily/scale.cc | 109 +++++++++++++++++++++++++++++++++++ scm/lily.scm | 6 ++ 6 files changed, 174 insertions(+), 24 deletions(-) create mode 100644 lily/scale.cc diff --git a/ChangeLog b/ChangeLog index 978139cc6d..93a4d4845c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2006-09-21 Han-Wen Nienhuys + + * lily/accidental-placement.cc (calc_positioning_done): don't + trigger Y-extent calculation too early. Use pure_height instead. + + * lily/scale.cc (LY_DEFINE): new file. + 2006-09-20 Joe Neeman * lily/page-breaking.cc (find_chunks_and_breaks): ignore breaks diff --git a/lily/accidental-placement.cc b/lily/accidental-placement.cc index ff68bbdf0a..199ff98c93 100644 --- a/lily/accidental-placement.cc +++ b/lily/accidental-placement.cc @@ -341,14 +341,6 @@ Accidental_placement::calc_positioning_done (SCM smob) Accidental_placement_entry *head_ape = new Accidental_placement_entry; common[X_AXIS] = common_refpoint_of_array (heads, common[X_AXIS], X_AXIS); vector head_skyline (empty_skyline (LEFT)); - - vector stems; - for (vsize i = 0; i < heads.size (); i++) - if (Grob *s = Rhythmic_head::get_stem (heads[i])) - stems.push_back (s); - vector_sort (stems, less ()); - uniq (stems); - concat (heads, stems); vector head_extents; for (vsize i = heads.size (); i--;) @@ -359,6 +351,25 @@ Accidental_placement::calc_positioning_done (SCM smob) insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT); } + vector stems; + for (vsize i = 0; i < heads.size (); i++) + { + if (Grob *s = Rhythmic_head::get_stem (heads[i])) + stems.push_back (s); + } + + vector_sort (stems, less ()); + uniq (stems); + for (vsize i = 0; i < stems.size (); i ++) + { + int very_large = INT_MAX; + + Box b (heads[i]->extent (common[X_AXIS], X_AXIS), + heads[i]->pure_height (common[Y_AXIS], 0, very_large)); + + insert_extent_into_skyline (&head_skyline, b, Y_AXIS, LEFT); + } + head_ape->left_skyline_ = head_skyline; head_ape->offset_ = 0.0; diff --git a/lily/include/pitch.hh b/lily/include/pitch.hh index 57cb076b52..2ebbb71a41 100644 --- a/lily/include/pitch.hh +++ b/lily/include/pitch.hh @@ -12,6 +12,17 @@ #include "lily-proto.hh" #include "smobs.hh" +#include "std-vector.hh" + +struct Scale +{ + vector step_semitones_; + Scale (); + Scale (Scale const&); + DECLARE_SMOBS(Scale,); +}; + + /** A "tonal" pitch. This is a pitch used in diatonal western music (24 quartertones in an octave), as opposed to a frequency in Hz or a integer number of semitones. @@ -34,7 +45,8 @@ private: // fixme int notename_; int alteration_; int octave_; - + Scale *scale_; + void transpose (Pitch); void up_to (int); void down_to (int); @@ -84,6 +96,7 @@ INSTANTIATE_COMPARE (Pitch, Pitch::compare); extern SCM pitch_less_proc; Pitch pitch_interval (Pitch const &from, Pitch const &to); +extern Scale *default_global_scale; #endif /* MUSICAL_PITCH_HH */ diff --git a/lily/pitch.cc b/lily/pitch.cc index 80b32e3c69..566b729e24 100644 --- a/lily/pitch.cc +++ b/lily/pitch.cc @@ -19,6 +19,7 @@ Pitch::Pitch (int o, int n, int a) notename_ = n; alteration_ = a; octave_ = o; + scale_ = default_global_scale; normalise (); } @@ -27,6 +28,7 @@ Pitch::Pitch () { notename_ = 0; alteration_ = 0; + scale_ = default_global_scale; octave_ = 0; } @@ -49,11 +51,13 @@ Pitch::compare (Pitch const &m1, Pitch const &m2) int Pitch::steps () const { - return notename_ + octave_ * 7; + return notename_ + octave_ * scale_->step_semitones_.size (); } /* Should be settable from input? */ -static Byte diatonic_scale_semitones[ ] = { 0, 2, 4, 5, 7, 9, 11 }; +// static Byte diatonic_scale_semitones[ ] = { 0, 2, 4, 5, 7, 9, 11 }; + + /* Calculate pitch height in 12th octave steps. Don't assume normalised pitch as this function is used to normalise the pitch. */ @@ -64,15 +68,15 @@ Pitch::semitone_pitch () const int n = notename_; while (n < 0) { - n += 7; + n += scale_->step_semitones_.size (); o--; } if (alteration_ % 2) programming_error ("semitone_pitch () called on quarter tone alteration."); - return ((o + n / 7) * 12 - + diatonic_scale_semitones[n % 7] + return ((o + n / scale_->step_semitones_.size ()) * 12 + + scale_->step_semitones_[n % scale_->step_semitones_.size ()] + (alteration_ / 2)); } @@ -83,12 +87,12 @@ Pitch::quartertone_pitch () const int n = notename_; while (n < 0) { - n += 7; + n += scale_->step_semitones_.size (); o--; } - return ((o + n / 7) * 24 - + 2 * diatonic_scale_semitones[n % 7] + return ((o + n / scale_->step_semitones_.size ()) * 24 + + 2 * scale_->step_semitones_[n % scale_->step_semitones_.size ()] + alteration_); } @@ -96,15 +100,15 @@ void Pitch::normalise () { int pitch = quartertone_pitch (); - while (notename_ >= 7) + while (notename_ >= (int) scale_->step_semitones_.size ()) { - notename_ -= 7; + notename_ -= scale_->step_semitones_.size (); octave_++; alteration_ -= quartertone_pitch () - pitch; } while (notename_ < 0) { - notename_ += 7; + notename_ += scale_->step_semitones_.size (); octave_--; alteration_ -= quartertone_pitch () - pitch; } @@ -169,7 +173,7 @@ char const *accname[] = {"eses", "eseh", "es", "eh", "", string Pitch::to_string () const { - int n = (notename_ + 2) % 7; + int n = (notename_ + 2) % scale_->step_semitones_.size (); string s = ::to_string (char (n + 'a')); if (alteration_) s += string (accname[alteration_ - DOUBLE_FLAT]); @@ -234,11 +238,11 @@ Pitch::down_to (int notename) } IMPLEMENT_TYPE_P (Pitch, "ly:pitch?"); - SCM -Pitch::mark_smob (SCM) +Pitch::mark_smob (SCM x) { - return SCM_EOL; + Pitch *p = (Pitch*) SCM_CELL_WORD_1 (x); + return p->scale_->self_scm (); } IMPLEMENT_SIMPLE_SMOBS (Pitch); diff --git a/lily/scale.cc b/lily/scale.cc new file mode 100644 index 0000000000..b71f43fe20 --- /dev/null +++ b/lily/scale.cc @@ -0,0 +1,109 @@ +/* + scale.cc -- implement Scale + + source file of the GNU LilyPond music typesetter + + (c) 2006 Han-Wen Nienhuys + +*/ + +#include "pitch.hh" + +#include "ly-smobs.icc" + +LY_DEFINE (ly_make_scale, "ly:make-scale", + 1, 0, 0, (SCM steps), + "Create a scale. Takes a vector of ints as argument") +{ + bool type_ok = scm_is_vector (steps); + + vector semitones; + if (type_ok) + { + int len = scm_c_vector_length (steps); + for (int i = 0 ; i < len; i++) + { + SCM step = scm_c_vector_ref (steps, i); + type_ok = type_ok && scm_is_integer (step); + if (type_ok) + semitones.push_back (scm_to_int (step)); + } + } + + + SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of int"); + + + Scale *s = new Scale; + s->step_semitones_ = semitones; + + SCM retval = s->self_scm (); + + s->unprotect (); + + return retval; +} + +LY_DEFINE (ly_default_scale, "ly:default-scale", + 0, 0, 0, (), + "Get the global default scale.") +{ + return default_global_scale + ? SCM_BOOL_F + : default_global_scale->self_scm (); +} + + +Scale * default_global_scale = 0; + +LY_DEFINE (ly_set_default_scale, "ly:set-default-scale", + 1, 0, 0, (SCM scale), + "Set the global default scale.") +{ + Scale *s = Scale::unsmob (scale); + SCM_ASSERT_TYPE (s, scale, SCM_ARG1, __FUNCTION__, "scale"); + + if (default_global_scale) + default_global_scale->unprotect (); + default_global_scale = s; + s->protect (); + + return SCM_UNSPECIFIED; +} + + +int +Scale::print_smob (SCM x, SCM port, scm_print_state *) +{ + (void) x; + + scm_puts ("#", port); + return 1; +} + + +SCM +Scale::mark_smob (SCM x) +{ + (void) x; + return SCM_UNSPECIFIED; +} + +Scale::Scale () +{ + smobify_self (); +} + +Scale::Scale (Scale const &src) +{ + step_semitones_ = src.step_semitones_; + smobify_self (); +} + + +Scale::~Scale () +{ +} + +IMPLEMENT_SMOBS(Scale); +IMPLEMENT_DEFAULT_EQUAL_P(Scale); diff --git a/scm/lily.scm b/scm/lily.scm index 495234fb92..0bb09baffc 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -237,7 +237,13 @@ The syntax is the same as `define*-public'." safe-objects)) ,safe-symbol))) +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; +;; init pitch system + +(ly:set-default-scale (ly:make-scale #(0 2 4 5 7 9 11))) + + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; other files. -- 2.39.2