From adaa7aecab8595596fc6505402b40a37a04716e6 Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Fri, 22 Dec 2006 19:06:47 +0100 Subject: [PATCH] use rational numbers for alteration field of Pitch. --- input/regression/GNUmakefile | 11 + input/regression/key-signature-scordatura.ly | 4 +- input/regression/keys.ly | 2 +- lily/accidental-engraver.cc | 20 +- lily/accidental.cc | 3 - lily/align-interface.cc | 2 +- lily/ambitus-engraver.cc | 6 +- lily/guile-init.cc | 54 +++ lily/include/audio-item.hh | 2 +- lily/include/lily-guile.hh | 2 + lily/include/lily-proto.hh | 1 + lily/include/midi-item.hh | 2 +- lily/include/pitch.hh | 76 ++-- lily/include/scale.hh | 29 ++ lily/key-engraver.cc | 37 +- lily/key-performer.cc | 10 +- lily/key-signature-interface.cc | 6 +- lily/lily-guile.cc | 389 ++++++++++--------- lily/midi-item.cc | 24 +- lily/midi-walker.cc | 2 +- lily/music-scheme.cc | 8 +- lily/music.cc | 5 +- lily/note-performer.cc | 2 +- lily/parser.yy | 12 +- lily/pitch-scheme.cc | 26 +- lily/pitch.cc | 111 +++--- lily/pitched-trill-engraver.cc | 4 +- lily/relative-octave-check.cc | 3 +- lily/scale.cc | 22 +- lily/tab-note-heads-engraver.cc | 2 +- ly/engraver-init.ly | 4 +- scm/chord-entry.scm | 2 + scm/lily-library.scm | 29 +- scm/lily.scm | 2 +- 34 files changed, 524 insertions(+), 390 deletions(-) create mode 100644 lily/guile-init.cc create mode 100644 lily/include/scale.hh diff --git a/input/regression/GNUmakefile b/input/regression/GNUmakefile index df3a19a13b..461a2c3e6e 100644 --- a/input/regression/GNUmakefile +++ b/input/regression/GNUmakefile @@ -6,3 +6,14 @@ LOCALSTEPMAKE_TEMPLATES=lilypond ly lysdoc include $(depth)/make/stepmake.make TITLE=LilyPond Regression Tests + +test: + $(MAKE) out=test WWW ANTI_ALIAS_FACTOR=1 + + +CHECK_SOURCE=$(HOME)/vc/gub/target/linux-x86/build/lilypond-master-git.sv.gnu.org-lilypond.git/input/regression/out-test/ +RESULT_DIR=$(top-build-dir)/out/test-results/ +check: + rm -rf $(RESULT_DIR) + mkdir -p $(RESULT_DIR) + $(PYTHON) $(buildscript-dir)/output-distance.py --output-dir $(RESULT_DIR) $(CHECK_SOURCE) out-test/ diff --git a/input/regression/key-signature-scordatura.ly b/input/regression/key-signature-scordatura.ly index 456bc1a629..cfad4a74bf 100644 --- a/input/regression/key-signature-scordatura.ly +++ b/input/regression/key-signature-scordatura.ly @@ -11,9 +11,9 @@ key signatures can be set invidually per pitch. } \relative c' \new Staff { - \set Staff.keySignature = #'(((1 . 2) . 1) ((0 . 3) . -1)) + \set Staff.keySignature = #`(((1 . 2) . ,SHARP) ((0 . 3) . ,FLAT)) f8 a c e - \set Staff.keySignature = #'(((1 . 2) . -1) ((0 . 4) . 2)) + \set Staff.keySignature = #`(((1 . 2) . ,FLAT) ((0 . 4) . ,DOUBLE-SHARP)) e a, g a } diff --git a/input/regression/keys.ly b/input/regression/keys.ly index 65ba2796e8..0a071d9bd6 100644 --- a/input/regression/keys.ly +++ b/input/regression/keys.ly @@ -25,7 +25,7 @@ are created also on a clef change. \break \key bes \major % \major c2 \clef alto c2 \key d \major \clef treble c2 - \set Staff.keySignature = #'((2 . -1) (6 . 3) (4 . -2)) + \set Staff.keySignature = #`((2 . ,SEMI-FLAT) (6 . ,THREE-Q-SHARP) (4 . ,FLAT)) e2 } diff --git a/lily/accidental-engraver.cc b/lily/accidental-engraver.cc index a94f553d06..a325a017d6 100644 --- a/lily/accidental-engraver.cc +++ b/lily/accidental-engraver.cc @@ -151,13 +151,13 @@ recent_enough (int bar_number, SCM alteration_def, SCM laziness) return (bar_number <= scm_to_int (scm_cdr (alteration_def)) + scm_to_int (laziness)); } -static int +static Rational extract_alteration (SCM alteration_def) { if (scm_is_number (alteration_def)) - return scm_to_int (alteration_def); + return ly_scm2rational (alteration_def); else if (scm_is_pair (alteration_def)) - return scm_to_int (scm_car (alteration_def)); + return ly_scm2rational (scm_car (alteration_def)); else if (alteration_def == SCM_BOOL_F) return 0; else @@ -215,13 +215,13 @@ number_accidentals_from_sig (bool *different, SCM sig, Pitch *pitch, } else { - int prev = extract_alteration (previous_alteration); - int alter = pitch->get_alteration (); + Rational prev = extract_alteration (previous_alteration); + Rational alter = pitch->get_alteration (); if (alter == prev) num = 0; - else if ((abs (alter) < abs (prev) - || prev * alter < 0) && alter != 0) + else if ((alter.abs () < prev.abs () + || (prev * alter).sign () < 0) && alter.sign ()) num = 2; *different = (alter != prev); } @@ -376,7 +376,7 @@ Accidental_engraver::create_accidental (Accidental_entry *entry, else a = make_standard_accidental (note, support, entry->origin_engraver_); - SCM accs = scm_cons (scm_from_int (pitch->get_alteration ()), + SCM accs = scm_cons (scm_from_int (pitch->get_alteration () * Rational (4)), SCM_EOL); if (restore_natural) { @@ -489,7 +489,7 @@ Accidental_engraver::stop_translation_timestep () int n = pitch->get_notename (); int o = pitch->get_octave (); - int a = pitch->get_alteration (); + Rational a = pitch->get_alteration (); SCM key = scm_cons (scm_from_int (o), scm_from_int (n)); SCM localsig = SCM_EOL; @@ -515,7 +515,7 @@ Accidental_engraver::stop_translation_timestep () noteheads with the same notename. */ localsig = ly_assoc_front_x (localsig, key, - scm_cons (scm_from_int (a), + scm_cons (ly_rational2scm (a), scm_from_int (barnum))); change = true; } diff --git a/lily/accidental.cc b/lily/accidental.cc index 060c97849d..6b9718f61c 100644 --- a/lily/accidental.cc +++ b/lily/accidental.cc @@ -251,9 +251,6 @@ Accidental_interface::print (SCM smob) return mol.smobbed_copy (); } -/* - TODO: should move avoid-slur into item? -*/ ADD_INTERFACE (Accidental_interface, "a single accidental", "accidentals " diff --git a/lily/align-interface.cc b/lily/align-interface.cc index 58cd7098cc..0bf83bf354 100644 --- a/lily/align-interface.cc +++ b/lily/align-interface.cc @@ -60,7 +60,7 @@ Align_interface::stretch_after_break (SCM grob) for (vsize i = 0; i < elems.size (); i++) elems[i]->relative_coordinate (common, Y_AXIS); - SCM details = me_spanner->get_bound (LEFT)->get_property ("line-break-system-details"); + SCM details = me_spanner->get_bound (LEFT)->get_property ("line-break-system-details"); SCM extra_space_handle = scm_assoc (ly_symbol2scm ("fixed-alignment-extra-space"), details); Real extra_space = robust_scm2double (scm_is_pair (extra_space_handle) diff --git a/lily/ambitus-engraver.cc b/lily/ambitus-engraver.cc index 5946b91c6d..8f617652bf 100644 --- a/lily/ambitus-engraver.cc +++ b/lily/ambitus-engraver.cc @@ -148,8 +148,8 @@ Ambitus_engraver::finalize () handle = scm_assoc (scm_from_int (p.get_notename ()), start_key_sig_); - int sig_alter = (handle != SCM_BOOL_F) - ? scm_to_int (scm_cdr (handle)) : 0; + Rational sig_alter = (handle != SCM_BOOL_F) + ? ly_scm2rational (scm_cdr (handle)) : Rational (0); if (sig_alter == p.get_alteration ()) { @@ -158,7 +158,7 @@ Ambitus_engraver::finalize () } else { - SCM l = scm_list_1 (scm_from_int (p.get_alteration ())); + SCM l = scm_list_1 (scm_from_int (int (Real (Rational (4) * p.get_alteration ())))); accidentals_[d]->set_property ("accidentals", l); } } diff --git a/lily/guile-init.cc b/lily/guile-init.cc new file mode 100644 index 0000000000..77fd7c59f3 --- /dev/null +++ b/lily/guile-init.cc @@ -0,0 +1,54 @@ +/* + guile-init.cc -- implement GUILE init routines. + + source file of the GNU LilyPond music typesetter + + (c) 2006 Han-Wen Nienhuys + +*/ + +#include "lily-guile.hh" +#include "main.hh" +#include "warn.hh" + +/* + INIT +*/ + + +typedef void (*Void_fptr) (); +vector *scm_init_funcs_; + +void add_scm_init_func (void (*f) ()) +{ + if (!scm_init_funcs_) + scm_init_funcs_ = new vector; + + scm_init_funcs_->push_back (f); +} + +void +ly_init_ly_module (void *) +{ + for (vsize i = scm_init_funcs_->size (); i--;) + (scm_init_funcs_->at (i)) (); + + if (be_verbose_global) + { + progress_indication ("["); + scm_display (scm_c_eval_string ("(%search-load-path \"lily.scm\")"), + scm_current_error_port ()); + progress_indication ("]\n"); + } + + scm_primitive_load_path (scm_makfrom0str ("lily.scm")); +} + +SCM global_lily_module; + +void +ly_c_init_guile () +{ + global_lily_module = scm_c_define_module ("lily", ly_init_ly_module, 0); + scm_c_use_module ("lily"); +} diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index 11f3cd31f5..43009195c3 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -55,7 +55,7 @@ public: class Audio_note : public Audio_item { public: - Audio_note (Pitch p, Moment m, bool tie_event, int transposing_i); + Audio_note (Pitch p, Moment m, bool tie_event, int transposing); void tie_to (Audio_note *); diff --git a/lily/include/lily-guile.hh b/lily/include/lily-guile.hh index 621849edc6..c2cfb8ebfc 100644 --- a/lily/include/lily-guile.hh +++ b/lily/include/lily-guile.hh @@ -45,6 +45,8 @@ string gulp_file_to_string (string fn, bool must_exist, int size); string ly_scm2string (SCM s); string ly_symbol2string (SCM); +Rational ly_scm2rational (SCM); +SCM ly_rational2scm (Rational); SCM ly_offset2scm (Offset); Offset ly_scm2offset (SCM); SCM ly_chain_assoc (SCM key, SCM achain); diff --git a/lily/include/lily-proto.hh b/lily/include/lily-proto.hh index c3082aaddd..d0b7c65b64 100644 --- a/lily/include/lily-proto.hh +++ b/lily/include/lily-proto.hh @@ -135,6 +135,7 @@ class Property_iterator; class Rational; class Relative_octave_music; class Repeated_music; +class Scale; class Scheme_hash_table; class Score; class Score_context; diff --git a/lily/include/midi-item.hh b/lily/include/midi-item.hh index 6ec530f68c..a7e7ceb512 100644 --- a/lily/include/midi-item.hh +++ b/lily/include/midi-item.hh @@ -135,7 +135,7 @@ public: DECLARE_CLASSNAME(Midi_note); Moment get_length () const; - int get_pitch () const; + int get_semitone_pitch () const; int get_fine_tuning () const; virtual string to_string () const; diff --git a/lily/include/pitch.hh b/lily/include/pitch.hh index f50d2d531c..0e3be73917 100644 --- a/lily/include/pitch.hh +++ b/lily/include/pitch.hh @@ -11,16 +11,7 @@ #include "lily-proto.hh" #include "smobs.hh" - -#include "std-vector.hh" - -struct Scale -{ - vector step_semitones_; - Scale (); - Scale (Scale const&); - DECLARE_SMOBS (Scale); -}; +#include "rational.hh" /** A "tonal" pitch. This is a pitch used in diatonal western music @@ -30,35 +21,27 @@ struct Scale Pitch is lexicographically ordered by (octave, notename, alteration). - - TODO: - - - add indeterminate octaves, so it can be used as a key in keySigature */ class Pitch { -private: // fixme - /* - TODO: use SCM - */ - - int notename_; - int alteration_; +private: int octave_; + int notename_; + Rational alteration_; Scale *scale_; - + void transpose (Pitch); void up_to (int); void down_to (int); - void normalise (); + void normalize (); public: - int get_octave () const; int get_notename () const; - int get_alteration () const; + Rational get_alteration () const; - Pitch (int octave, int notename, int accidental); + Pitch (int octave, int notename, Rational accidental); + Pitch (int octave, int notename); Pitch (); Pitch transposed (Pitch) const; @@ -67,26 +50,38 @@ public: static int compare (Pitch const &, Pitch const &); int steps () const; - int semitone_pitch () const; - int quartertone_pitch () const; + Rational tone_pitch () const; + int rounded_semitone_pitch () const; + int rounded_quartertone_pitch () const; + string to_string () const; DECLARE_SCHEME_CALLBACK (less_p, (SCM a, SCM b)); DECLARE_SIMPLE_SMOBS (Pitch); }; -enum - { - DOUBLE_FLAT = -4, - THREE_Q_FLAT, - FLAT, - SEMI_FLAT, - NATURAL, - SEMI_SHARP, - SHARP, - THREE_Q_SHARP, - DOUBLE_SHARP, - }; + +enum { + DOUBLE_FLAT = -4, + THREE_Q_FLAT, + FLAT, + SEMI_FLAT, + NATURAL, + SEMI_SHARP, + SHARP, + THREE_Q_SHARP, + DOUBLE_SHARP, +}; + +extern Rational DOUBLE_FLAT_ALTERATION; +extern Rational THREE_Q_FLAT_ALTERATION; +extern Rational FLAT_ALTERATION; +extern Rational SEMI_FLAT_ALTERATION; +extern Rational NATURAL_ALTERATION; +extern Rational SEMI_SHARP_ALTERATION; +extern Rational SHARP_ALTERATION; +extern Rational THREE_Q_SHARP_ALTERATION; +extern Rational DOUBLE_SHARP_ALTERATION; SCM ly_pitch_diff (SCM pitch, SCM root); SCM ly_pitch_transpose (SCM p, SCM delta); @@ -96,7 +91,6 @@ 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/include/scale.hh b/lily/include/scale.hh new file mode 100644 index 0000000000..58bec89eb5 --- /dev/null +++ b/lily/include/scale.hh @@ -0,0 +1,29 @@ +/* + scale.hh -- declare Scale + + source file of the GNU LilyPond music typesetter + + (c) 2006 Han-Wen Nienhuys + +*/ + +#ifndef SCALE_HH +#define SCALE_HH + +#include "smobs.hh" +#include "rational.hh" +#include "std-vector.hh" + +struct Scale +{ + vector step_tones_; + Scale (); + Scale (Scale const&); + DECLARE_SMOBS (Scale); +}; + +extern Scale *default_global_scale; + +#endif /* SCALE_HH */ + + diff --git a/lily/key-engraver.cc b/lily/key-engraver.cc index 41cb7aed50..54c9832cc8 100644 --- a/lily/key-engraver.cc +++ b/lily/key-engraver.cc @@ -18,13 +18,6 @@ #include "translator.icc" -/* - TODO: The representation of key sigs is all fucked. -*/ - -/** - Make the key signature. -*/ class Key_engraver : public Engraver { void create_key (bool); @@ -59,6 +52,24 @@ Key_engraver::Key_engraver () cancellation_ = 0; } + +SCM +make_qt_key (SCM rat_key) +{ + SCM qt_key = SCM_EOL; + SCM *tail = &qt_key; + + for (SCM s = rat_key; scm_is_pair (s); s = scm_cdr (s)) + { + *tail = scm_cons (scm_cons (scm_caar (s), + scm_from_int (Rational (4)* ly_scm2rational (scm_cdar (s)))), + SCM_EOL); + tail = SCM_CDRLOC (*tail); + } + + return qt_key; +} + void Key_engraver::create_key (bool is_default) { @@ -83,10 +94,10 @@ Key_engraver::create_key (bool is_default) for (SCM s = last; scm_is_pair (s); s = scm_cdr (s)) { SCM new_alter_pair = scm_assoc (scm_caar (s), key); - int old_alter = scm_to_int (scm_cdar (s)); + Rational old_alter = ly_scm2rational (scm_cdar (s)); if (new_alter_pair == SCM_BOOL_F || extranatural - && (scm_to_int(scm_cdr(new_alter_pair))-old_alter)*old_alter < 0) + && (ly_scm2rational (scm_cdr (new_alter_pair)) - old_alter)*old_alter < Rational (0)) { *tail = scm_cons (scm_car (s), *tail); tail = SCM_CDRLOC (*tail); @@ -99,12 +110,14 @@ Key_engraver::create_key (bool is_default) key_event_ ? key_event_->self_scm () : SCM_EOL); - cancellation_->set_property ("alteration-alist", restore); + cancellation_->set_property ("alteration-alist", make_qt_key (restore)); cancellation_->set_property ("c0-position", get_property ("middleCPosition")); } } - item_->set_property ("alteration-alist", key); + + + item_->set_property ("alteration-alist", make_qt_key (key)); } if (!is_default) @@ -179,7 +192,7 @@ Key_engraver::read_event (Stream_event const *r) } for (SCM s = n; scm_is_pair (s); s = scm_cdr (s)) - if (scm_to_int (scm_cdar (s))) + if (ly_scm2rational (scm_cdar (s))) accs = scm_cons (scm_car (s), accs); context ()->set_property ("keySignature", accs); diff --git a/lily/key-performer.cc b/lily/key-performer.cc index 61e3592630..9bb8b11a48 100644 --- a/lily/key-performer.cc +++ b/lily/key-performer.cc @@ -66,8 +66,8 @@ Key_performer::process_music () SCM third = scm_assoc (scm_from_int (2), c_pitchlist); bool minor = (scm_is_pair (third) - && scm_is_integer (scm_cdr (third)) - && scm_to_int (scm_cdr (third)) == FLAT); + && scm_is_number (scm_cdr (third)) + && ly_scm2rational (scm_cdr (third)) == FLAT_ALTERATION); audio_ = new Audio_key (scm_to_int (acc), !minor); @@ -96,5 +96,7 @@ Key_performer::listen_key_change (Stream_event *ev) } ADD_TRANSLATOR (Key_performer, - "", "", - "", ""); + "", + "", + "", + ""); diff --git a/lily/key-signature-interface.cc b/lily/key-signature-interface.cc index 37f985697e..a6ff448943 100644 --- a/lily/key-signature-interface.cc +++ b/lily/key-signature-interface.cc @@ -160,4 +160,8 @@ Key_signature_interface::print (SCM smob) ADD_INTERFACE (Key_signature_interface, "A group of accidentals, to be printed as signature sign.", - "style c0-position alteration-alist"); + + "c0-position " + "style " + "alteration-alist " + ); diff --git a/lily/lily-guile.cc b/lily/lily-guile.cc index d57a9f5730..182ed7e02a 100644 --- a/lily/lily-guile.cc +++ b/lily/lily-guile.cc @@ -30,8 +30,10 @@ using namespace std; #include "version.hh" #include "warn.hh" -// #define TEST_GC +/* + symbols/strings. + */ SCM ly_to_symbol (SCM scm) { @@ -46,12 +48,6 @@ ly_to_string (SCM scm) scm_makfrom0str ("~S"), scm); } -SCM -ly_last (SCM list) -{ - return scm_car (scm_last_pair (list)); -} - SCM ly_write2scm (SCM s) { @@ -122,6 +118,9 @@ extern "C" { } }; +/* + STRINGS + */ string ly_scm2string (SCM str) { @@ -149,6 +148,10 @@ ly_scm2newstr (SCM str, size_t *lenp) return 0; } + +/* + PAIRS +*/ SCM index_get_cell (SCM s, Direction d) { @@ -174,77 +177,62 @@ is_number_pair (SCM p) && scm_is_number (scm_car (p)) && scm_is_number (scm_cdr (p)); } -typedef void (*Void_fptr) (); -vector *scm_init_funcs_; -void add_scm_init_func (void (*f) ()) +unsigned int +ly_scm_hash (SCM s) { - if (!scm_init_funcs_) - scm_init_funcs_ = new vector; - - scm_init_funcs_->push_back (f); + return scm_ihashv (s, ~1u); } -void -ly_init_ly_module (void *) -{ - for (vsize i = scm_init_funcs_->size (); i--;) - (scm_init_funcs_->at (i)) (); - if (be_verbose_global) +bool +is_axis (SCM s) +{ + if (scm_is_number (s)) { - progress_indication ("["); - scm_display (scm_c_eval_string ("(%search-load-path \"lily.scm\")"), - scm_current_error_port ()); - progress_indication ("]\n"); + int i = scm_to_int (s); + return i == 0 || i == 1; } - - scm_primitive_load_path (scm_makfrom0str ("lily.scm")); + return false; } -SCM global_lily_module; - -void -ly_c_init_guile () +bool +to_boolean (SCM s) { - global_lily_module = scm_c_define_module ("lily", ly_init_ly_module, 0); - scm_c_use_module ("lily"); + return scm_is_bool (s) && ly_scm2bool (s); } -unsigned int -ly_scm_hash (SCM s) +/* + DIRECTIONS + */ +Direction +to_dir (SCM s) { - return scm_ihashv (s, ~1u); + return scm_is_integer (s) ? (Direction) scm_to_int (s) : CENTER; } -bool -is_direction (SCM s) +Direction +robust_scm2dir (SCM d, Direction def) { - if (scm_is_number (s)) - { - int i = scm_to_int (s); - return i >= -1 && i <= 1; - } - return false; + if (is_direction (d)) + def = to_dir (d); + return def; } bool -is_axis (SCM s) +is_direction (SCM s) { if (scm_is_number (s)) { int i = scm_to_int (s); - return i == 0 || i == 1; + return i >= -1 && i <= 1; } return false; } -Direction -to_dir (SCM s) -{ - return scm_is_integer (s) ? (Direction) scm_to_int (s) : CENTER; -} - +/* + INTERVALS + */ Interval ly_scm2interval (SCM p) { @@ -264,32 +252,40 @@ ly_interval2scm (Drul_array i) return scm_cons (scm_from_double (i[LEFT]), scm_from_double (i[RIGHT])); } -bool -to_boolean (SCM s) + +Interval +robust_scm2interval (SCM k, Drul_array v) { - return scm_is_bool (s) && ly_scm2bool (s); + Interval i; + i[LEFT] = v[LEFT]; + i[RIGHT] = v[RIGHT]; + if (is_number_pair (k)) + i = ly_scm2interval (k); + return i; } -/* Appendable list L: the cdr contains the list, the car the last cons - in the list. */ -SCM -appendable_list () +Drul_array +robust_scm2drul (SCM k, Drul_array v) { - SCM s = scm_cons (SCM_EOL, SCM_EOL); - scm_set_car_x (s, s); - - return s; + if (is_number_pair (k)) + v = ly_scm2interval (k); + return v; } -void -appendable_list_append (SCM l, SCM elt) +Drul_array +robust_scm2booldrul (SCM k, Drul_array def) { - SCM newcons = scm_cons (elt, SCM_EOL); - - scm_set_cdr_x (scm_car (l), newcons); - scm_set_car_x (l, newcons); + if (scm_is_pair (k)) + { + def[LEFT] = to_boolean (scm_car (k)); + def[RIGHT] = to_boolean (scm_cdr (k)); + } + return def; } +/* + OFFSET +*/ SCM ly_offset2scm (Offset o) { @@ -303,6 +299,13 @@ ly_scm2offset (SCM s) scm_to_double (scm_cdr (s))); } +Offset +robust_scm2offset (SCM k, Offset o) +{ + if (is_number_pair (k)) + o = ly_scm2offset (k); + return o; +} SCM ly_offsets2scm (vector os) { @@ -325,23 +328,12 @@ ly_scm2offsets (SCM s) return os; } -SCM -ly_deep_copy (SCM src) -{ - if (scm_is_pair (src)) - return scm_cons (ly_deep_copy (scm_car (src)), ly_deep_copy (scm_cdr (src))); - else if (scm_is_vector (src)) - { - int len = scm_c_vector_length (src); - SCM nv = scm_c_make_vector (len, SCM_UNDEFINED); - for (int i = 0;i < len; i++) - { - SCM si = scm_from_int (i); - scm_vector_set_x (nv, si, ly_deep_copy (scm_vector_ref (src, si))); - } - } - return src; -} + + + +/* + ALIST +*/ /* looks the key up in the cdrs of the alist-keys - ignoring the car and ignoring non-pair keys. @@ -373,27 +365,70 @@ ly_assoc_cdr (SCM key, SCM alist) return SCM_BOOL_F; } + +bool +alist_equal_p (SCM a, SCM b) +{ + for (SCM s = a; + scm_is_pair (s); s = scm_cdr (s)) + { + SCM key = scm_caar (s); + SCM val = scm_cdar (s); + SCM l = scm_assoc (key, b); + + if (l == SCM_BOOL_F + || !ly_is_equal (scm_cdr (l), val)) + + return false; + } + return true; +} + SCM -ly_string_array_to_scm (vector a) +ly_alist_vals (SCM alist) { - SCM s = SCM_EOL; - for (vsize i = a.size (); i ; i--) - s = scm_cons (ly_symbol2scm (a[i - 1].c_str ()), s); - return s; + SCM x = SCM_EOL; + for (SCM p = alist; scm_is_pair (p); p = scm_cdr (p)) + x = scm_cons (scm_cdar (p), x); + return x; } -/* SYMBOLS is a whitespace separated list. */ +/* + LISTS + */ + +/* Return I-th element, or last elt L. If I < 0, then we take the first + element. + + PRE: length (L) > 0 */ SCM -parse_symbol_list (char const *symbols) +robust_list_ref (int i, SCM l) { - while (isspace (*symbols)) - *symbols++; - string s = symbols; - replace_all (s, '\n', ' '); - replace_all (s, '\t', ' '); - return ly_string_array_to_scm (string_split (s, ' ')); + while (i-- > 0 && scm_is_pair (scm_cdr (l))) + l = scm_cdr (l); + return scm_car (l); } + +SCM +ly_deep_copy (SCM src) +{ + if (scm_is_pair (src)) + return scm_cons (ly_deep_copy (scm_car (src)), ly_deep_copy (scm_cdr (src))); + else if (scm_is_vector (src)) + { + int len = scm_c_vector_length (src); + SCM nv = scm_c_make_vector (len, SCM_UNDEFINED); + for (int i = 0;i < len; i++) + { + SCM si = scm_from_int (i); + scm_vector_set_x (nv, si, ly_deep_copy (scm_vector_ref (src, si))); + } + } + return src; +} + + SCM ly_truncate_list (int k, SCM lst) { @@ -412,6 +447,30 @@ ly_truncate_list (int k, SCM lst) return lst; } + + + +/* Appendable list L: the cdr contains the list, the car the last cons + in the list. */ +SCM +appendable_list () +{ + SCM s = scm_cons (SCM_EOL, SCM_EOL); + scm_set_car_x (s, s); + + return s; +} + +void +appendable_list_append (SCM l, SCM elt) +{ + SCM newcons = scm_cons (elt, SCM_EOL); + + scm_set_cdr_x (scm_car (l), newcons); + scm_set_car_x (l, newcons); +} + + string print_scm_val (SCM val) { @@ -506,6 +565,7 @@ ly_unique (SCM list) return scm_reverse_x (unique, SCM_EOL); } + static int scm_default_compare (void const *a, void const *b) { @@ -545,13 +605,6 @@ ly_list_qsort_uniq_x (SCM lst) return lst; } -/* tail add */ -SCM -ly_snoc (SCM s, SCM list) -{ - return ly_append2 (list, scm_list_n (s, SCM_UNDEFINED)); -} - /* Split list at member s, removing s. Return (BEFORE . AFTER) */ SCM @@ -607,18 +660,6 @@ int_list_to_slice (SCM l) return s; } -/* Return I-th element, or last elt L. If I < 0, then we take the first - element. - - PRE: length (L) > 0 */ -SCM -robust_list_ref (int i, SCM l) -{ - while (i-- > 0 && scm_is_pair (scm_cdr (l))) - l = scm_cdr (l); - return scm_car (l); -} - Real robust_scm2double (SCM k, double x) { @@ -627,51 +668,6 @@ robust_scm2double (SCM k, double x) return x; } -Direction -robust_scm2dir (SCM d, Direction def) -{ - if (is_direction (d)) - def = to_dir (d); - return def; -} - -Interval -robust_scm2interval (SCM k, Drul_array v) -{ - Interval i; - i[LEFT] = v[LEFT]; - i[RIGHT] = v[RIGHT]; - if (is_number_pair (k)) - i = ly_scm2interval (k); - return i; -} - -Drul_array -robust_scm2drul (SCM k, Drul_array v) -{ - if (is_number_pair (k)) - v = ly_scm2interval (k); - return v; -} - -Drul_array -robust_scm2booldrul (SCM k, Drul_array def) -{ - if (scm_is_pair (k)) - { - def[LEFT] = to_boolean (scm_car (k)); - def[RIGHT] = to_boolean (scm_cdr (k)); - } - return def; -} - -Offset -robust_scm2offset (SCM k, Offset o) -{ - if (is_number_pair (k)) - o = ly_scm2offset (k); - return o; -} string robust_scm2string (SCM k, string s) @@ -689,6 +685,22 @@ robust_scm2int (SCM k, int o) return o; } + +SCM +ly_rational2scm (Rational r) +{ + return scm_divide (scm_from_int (r.numerator ()), scm_from_int (r.denominator ())); +} + + +Rational +ly_scm2rational (SCM r) +{ + return Rational (scm_to_int (scm_numerator (r)), + scm_to_int (scm_denominator (r))); +} + + SCM alist_to_hashq (SCM alist) { @@ -705,33 +717,6 @@ alist_to_hashq (SCM alist) return tab; } -bool -alist_equal_p (SCM a, SCM b) -{ - for (SCM s = a; - scm_is_pair (s); s = scm_cdr (s)) - { - SCM key = scm_caar (s); - SCM val = scm_cdar (s); - SCM l = scm_assoc (key, b); - - if (l == SCM_BOOL_F - || !ly_is_equal (scm_cdr (l), val)) - - return false; - } - return true; -} - -SCM -ly_alist_vals (SCM alist) -{ - SCM x = SCM_EOL; - for (SCM p = alist; scm_is_pair (p); p = scm_cdr (p)) - x = scm_cons (scm_cdar (p), x); - return x; -} - SCM ly_hash2alist (SCM tab) { @@ -750,6 +735,10 @@ procedure_arity (SCM proc) return scm_to_int (fixed); } +/* + C++ interfacing. + */ + string mangle_cxx_identifier (string cxx_id) { @@ -769,3 +758,25 @@ mangle_cxx_identifier (string cxx_id) return cxx_id; } + + +SCM +ly_string_array_to_scm (vector a) +{ + SCM s = SCM_EOL; + for (vsize i = a.size (); i ; i--) + s = scm_cons (ly_symbol2scm (a[i - 1].c_str ()), s); + return s; +} + +/* SYMBOLS is a whitespace separated list. */ +SCM +parse_symbol_list (char const *symbols) +{ + while (isspace (*symbols)) + *symbols++; + string s = symbols; + replace_all (s, '\n', ' '); + replace_all (s, '\t', ' '); + return ly_string_array_to_scm (string_split (s, ' ')); +} diff --git a/lily/midi-item.cc b/lily/midi-item.cc index 88d303b4e7..10b7f2715c 100644 --- a/lily/midi-item.cc +++ b/lily/midi-item.cc @@ -258,22 +258,18 @@ Midi_note::get_length () const int Midi_note::get_fine_tuning () const { - int ft = audio_->pitch_.quartertone_pitch (); - ft -= 2 * audio_->pitch_.semitone_pitch (); - ft *= 50; // 1 quarter tone = 50 cents - return ft; + Rational tune = audio_->pitch_.tone_pitch () * Rational (2); + tune -= Rational (get_semitone_pitch ()); + + tune *= 100; + return (int) double (tune); } int -Midi_note::get_pitch () const +Midi_note::get_semitone_pitch () const { - int p = audio_->pitch_.semitone_pitch () + audio_->transposing_; - if (p == INT_MAX) - { - warning (_ ("silly pitch")); - p = 0; - } - return p; + return int (rint (double (audio_->pitch_.tone_pitch () * Rational (2, 1)))) + + audio_->transposing_; } string @@ -301,7 +297,7 @@ Midi_note::to_string () const } str += ::to_string ((char)status_byte); - str += ::to_string ((char) (get_pitch () + c0_pitch_)); + str += ::to_string ((char) (get_semitone_pitch () + c0_pitch_)); str += ::to_string ((char)dynamic_byte_); return str; @@ -326,7 +322,7 @@ Midi_note_off::to_string () const Byte status_byte = (char) (0x80 + channel_); string str = ::to_string ((char)status_byte); - str += ::to_string ((char) (get_pitch () + Midi_note::c0_pitch_)); + str += ::to_string ((char) (get_semitone_pitch () + Midi_note::c0_pitch_)); str += ::to_string ((char)aftertouch_byte_); if (get_fine_tuning () != 0) diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 2979c9380c..c2aaa085b1 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -63,7 +63,7 @@ Midi_walker::do_start_note (Midi_note *note) for (vsize i = 0; i < stop_note_queue.size (); i++) { /* if this pith already in queue */ - if (stop_note_queue[i].val->get_pitch () == note->get_pitch ()) + if (stop_note_queue[i].val->get_semitone_pitch () == note->get_semitone_pitch ()) { if (stop_note_queue[i].key < stop_mom) { diff --git a/lily/music-scheme.cc b/lily/music-scheme.cc index 365c3f4344..82f52a5c00 100644 --- a/lily/music-scheme.cc +++ b/lily/music-scheme.cc @@ -191,23 +191,23 @@ LY_DEFINE (ly_transpose_key_alist, "ly:transpose-key-alist", { Pitch orig (scm_to_int (scm_car (key)), scm_to_int (scm_cdr (key)), - scm_to_int (alter)); + ly_scm2rational (alter)); orig = orig.transposed (*p); SCM key = scm_cons (scm_from_int (orig.get_octave ()), scm_from_int (orig.get_notename ())); - newlist = scm_cons (scm_cons (key, scm_from_int (orig.get_alteration ())), + newlist = scm_cons (scm_cons (key, ly_rational2scm (orig.get_alteration ())), newlist); } else if (scm_is_number (key)) { - Pitch orig (0, scm_to_int (key), scm_to_int (alter)); + Pitch orig (0, scm_to_int (key), ly_scm2rational (alter)); orig = orig.transposed (*p); key = scm_from_int (orig.get_notename ()); - alter = scm_from_int (orig.get_alteration ()); + alter = ly_rational2scm (orig.get_alteration ()); newlist = scm_cons (scm_cons (key, alter), newlist); } } diff --git a/lily/music.cc b/lily/music.cc index fb272aae03..dd53e98643 100644 --- a/lily/music.cc +++ b/lily/music.cc @@ -202,7 +202,7 @@ transpose_mutable (SCM alist, Pitch delta) Pitch transposed = p->transposed (delta); scm_set_cdr_x (entry, transposed.smobbed_copy ()); - if (abs (transposed.get_alteration ()) > DOUBLE_SHARP) + if (transposed.get_alteration ().abs () > Rational (1,1)) { warning (_f ("transposition by %s makes alteration larger than double", delta.to_string ())); @@ -217,7 +217,8 @@ transpose_mutable (SCM alist, Pitch delta) transpose_music_list (val, delta); else if (prop == ly_symbol2scm ("pitch-alist") && scm_is_pair (val)) - entry = scm_cons (prop, ly_transpose_key_alist (val, delta.smobbed_copy ())); + entry = scm_cons (prop, + ly_transpose_key_alist (val, delta.smobbed_copy ())); retval = scm_cons (entry, retval); } diff --git a/lily/note-performer.cc b/lily/note-performer.cc index 8d9dfb44c1..e5c2ef9e05 100644 --- a/lily/note-performer.cc +++ b/lily/note-performer.cc @@ -42,7 +42,7 @@ Note_performer::process_music () SCM prop = get_property ("instrumentTransposition"); if (unsmob_pitch (prop)) - transposing = unsmob_pitch (prop)->semitone_pitch (); + transposing = unsmob_pitch (prop)->rounded_semitone_pitch (); while (note_evs_.size ()) { diff --git a/lily/parser.yy b/lily/parser.yy index 64d6103d44..ebb322d773 100644 --- a/lily/parser.yy +++ b/lily/parser.yy @@ -136,7 +136,7 @@ SCM make_music_relative (Pitch start, SCM music, Input loc); SCM run_music_function (Lily_parser *, SCM expr); SCM get_first_context_id (SCM type, Music *m); SCM make_chord_elements (SCM pitch, SCM dur, SCM modification_list); -SCM make_chord_step (int step, int alter); +SCM make_chord_step (int step, Rational alter); SCM make_simple_markup (SCM a); bool is_duration (int t); bool is_regular_identifier (SCM id); @@ -1661,7 +1661,7 @@ steno_tonic_pitch: $$ = p.smobbed_copy (); } | TONICNAME_PITCH sub_quotes { - Pitch p =* unsmob_pitch ($1); + Pitch p = *unsmob_pitch ($1); p = p.transposed (Pitch (-$2,0,0)); $$ = p.smobbed_copy (); @@ -2063,10 +2063,10 @@ step_number: $$ = make_chord_step ($1, 0); } | bare_unsigned '+' { - $$ = make_chord_step ($1, SHARP); + $$ = make_chord_step ($1, SHARP_ALTERATION); } | bare_unsigned CHORD_MINUS { - $$ = make_chord_step ($1, FLAT); + $$ = make_chord_step ($1, FLAT_ALTERATION); } ; @@ -2470,10 +2470,10 @@ set_music_properties (Music *p, SCM a) SCM -make_chord_step (int step, int alter) +make_chord_step (int step, Rational alter) { if (step == 7) - alter += FLAT; + alter += FLAT_ALTERATION; while (step < 0) step += 7; diff --git a/lily/pitch-scheme.cc b/lily/pitch-scheme.cc index 3beb9f43cf..16b78e9420 100644 --- a/lily/pitch-scheme.cc +++ b/lily/pitch-scheme.cc @@ -22,19 +22,21 @@ LY_DEFINE (ly_pitch_transpose, "ly:pitch-transpose", /* Should add optional args. */ LY_DEFINE (ly_make_pitch, "ly:make-pitch", - 3, 0, 0, (SCM octave, SCM note, SCM alter), + 2, 1, 0, (SCM octave, SCM note, SCM alter), "@var{octave} is specified by an integer, " "zero for the octave containing middle C. " "@var{note} is a number from 0 to 6, " "with 0 corresponding to C and 6 corresponding to B. " - "The @var{alter} is zero for a natural, negative for " - "flats, or positive for sharps. ") + "The @var{alter} is a rational number of whole tones for alteration.") { - SCM_ASSERT_TYPE (scm_integer_p (octave) == SCM_BOOL_T, octave, SCM_ARG1, __FUNCTION__, "integer"); - SCM_ASSERT_TYPE (scm_integer_p (note) == SCM_BOOL_T, note, SCM_ARG2, __FUNCTION__, "integer"); - SCM_ASSERT_TYPE (scm_integer_p (alter) == SCM_BOOL_T, alter, SCM_ARG3, __FUNCTION__, "integer"); - - Pitch p (scm_to_int (octave), scm_to_int (note), scm_to_int (alter)); + SCM_ASSERT_TYPE (scm_is_integer (octave), octave, SCM_ARG1, __FUNCTION__, "integer"); + SCM_ASSERT_TYPE (scm_is_integer (note), note, SCM_ARG2, __FUNCTION__, "integer"); + SCM_ASSERT_TYPE (scm_is_rational (alter), + alter, SCM_ARG3, __FUNCTION__, "rational"); + + Pitch p (scm_to_int (octave), scm_to_int (note), + ly_scm2rational (alter)); + return p.smobbed_copy (); } @@ -63,9 +65,9 @@ LY_DEFINE (ly_pitch_alteration, "ly:pitch-alteration", { Pitch *p = unsmob_pitch (pp); SCM_ASSERT_TYPE (p, pp, SCM_ARG1, __FUNCTION__, "Pitch"); - int q = p->get_alteration (); + Rational q = p->get_alteration (); - return scm_from_int (q); + return ly_rational2scm (q); } LY_DEFINE (pitch_notename, "ly:pitch-notename", @@ -84,7 +86,7 @@ LY_DEFINE (ly_pitch_quartertones, "ly:pitch-quartertones", { Pitch *p = unsmob_pitch (pp); SCM_ASSERT_TYPE (p, pp, SCM_ARG1, __FUNCTION__, "Pitch"); - int q = p->quartertone_pitch (); + int q = p->rounded_quartertone_pitch (); return scm_from_int (q); } @@ -94,7 +96,7 @@ LY_DEFINE (ly_pitch_semitones, "ly:pitch-semitones", { Pitch *p = unsmob_pitch (pp); SCM_ASSERT_TYPE (p, pp, SCM_ARG1, __FUNCTION__, "Pitch"); - int q = p->semitone_pitch (); + int q = p->rounded_semitone_pitch (); return scm_from_int (q); } diff --git a/lily/pitch.cc b/lily/pitch.cc index 566b729e24..4d983ab6d5 100644 --- a/lily/pitch.cc +++ b/lily/pitch.cc @@ -9,25 +9,26 @@ #include "pitch.hh" #include "main.hh" +#include "scale.hh" #include "string-convert.hh" #include "warn.hh" #include "ly-smobs.icc" -Pitch::Pitch (int o, int n, int a) + +Pitch::Pitch (int o, int n, Rational a) { notename_ = n; alteration_ = a; octave_ = o; scale_ = default_global_scale; - normalise (); + normalize (); } /* FIXME: why is octave == 0 and default not middleC ? */ Pitch::Pitch () { notename_ = 0; - alteration_ = 0; scale_ = default_global_scale; octave_ = 0; } @@ -37,7 +38,7 @@ Pitch::compare (Pitch const &m1, Pitch const &m2) { int o = m1.octave_ - m2.octave_; int n = m1.notename_ - m2.notename_; - int a = m1.alteration_ - m2.alteration_; + Rational a = m1.alteration_ - m2.alteration_; if (o) return o; @@ -45,76 +46,69 @@ Pitch::compare (Pitch const &m1, Pitch const &m2) return n; if (a) return a; + return 0; } int Pitch::steps () const { - return notename_ + octave_ * scale_->step_semitones_.size (); + return notename_ + octave_ * scale_->step_tones_.size (); } -/* Should be settable from input? */ -// 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. */ -int -Pitch::semitone_pitch () const +Rational +Pitch::tone_pitch () const { int o = octave_; int n = notename_; while (n < 0) { - n += scale_->step_semitones_.size (); + n += scale_->step_tones_.size (); o--; } - if (alteration_ % 2) - programming_error ("semitone_pitch () called on quarter tone alteration."); + Rational tones ((o + n / scale_->step_tones_.size ()) * 6, 1); + tones += scale_->step_tones_[n % scale_->step_tones_.size ()]; - return ((o + n / scale_->step_semitones_.size ()) * 12 - + scale_->step_semitones_[n % scale_->step_semitones_.size ()] - + (alteration_ / 2)); + tones += alteration_; + + return tones; } +/* Calculate pitch height in 12th octave steps. Don't assume + normalized pitch as this function is used to normalize the pitch. */ int -Pitch::quartertone_pitch () const +Pitch::rounded_semitone_pitch () const { - int o = octave_; - int n = notename_; - while (n < 0) - { - n += scale_->step_semitones_.size (); - o--; - } + return int (double (tone_pitch () * Rational (2))); +} - return ((o + n / scale_->step_semitones_.size ()) * 24 - + 2 * scale_->step_semitones_[n % scale_->step_semitones_.size ()] - + alteration_); +int +Pitch::rounded_quartertone_pitch () const +{ + return int (double (tone_pitch () * Rational (4))); } void -Pitch::normalise () +Pitch::normalize () { - int pitch = quartertone_pitch (); - while (notename_ >= (int) scale_->step_semitones_.size ()) + Rational pitch = tone_pitch (); + while (notename_ >= (int) scale_->step_tones_.size ()) { - notename_ -= scale_->step_semitones_.size (); + notename_ -= scale_->step_tones_.size (); octave_++; - alteration_ -= quartertone_pitch () - pitch; + alteration_ -= tone_pitch () - pitch; } while (notename_ < 0) { - notename_ += scale_->step_semitones_.size (); + notename_ += scale_->step_tones_.size (); octave_--; - alteration_ -= quartertone_pitch () - pitch; + alteration_ -= tone_pitch () - pitch; } - while (alteration_ > DOUBLE_SHARP) + + while (alteration_ > Rational (1)) { - if (notename_ == 6) + if (notename_ == int (scale_->step_tones_.size ())) { notename_ = 0; octave_++; @@ -122,47 +116,46 @@ Pitch::normalise () else notename_++; - alteration_ = 0; - alteration_ -= quartertone_pitch () - pitch; + alteration_ = Rational (0); + alteration_ -= tone_pitch () - pitch; } - - while (alteration_ < DOUBLE_FLAT) + while (alteration_ < Rational(-1)) { if (notename_ == 0) { - notename_ = 6; + notename_ = scale_->step_tones_.size (); octave_--; } else notename_--; alteration_ = 0; - alteration_ -= quartertone_pitch () - pitch; + alteration_ -= tone_pitch () - pitch; } } -/* WHugh, wat een intervaas */ void Pitch::transpose (Pitch delta) { - int new_semi = quartertone_pitch () +delta.quartertone_pitch (); + Rational new_alter = tone_pitch () + delta.tone_pitch (); + octave_ += delta.octave_; notename_ += delta.notename_; - alteration_ += new_semi - quartertone_pitch (); + alteration_ += new_alter - tone_pitch (); - normalise (); + normalize (); } Pitch pitch_interval (Pitch const &from, Pitch const &to) { - int sound = to.quartertone_pitch () - from.quartertone_pitch (); + Rational sound = to.tone_pitch () - from.tone_pitch (); Pitch pt (to.get_octave () - from.get_octave (), to.get_notename () - from.get_notename (), to.get_alteration () - from.get_alteration ()); - return pt.transposed (Pitch (0, 0, sound - pt.quartertone_pitch ())); + return pt.transposed (Pitch (0, 0, sound - pt.tone_pitch ())); } /* FIXME @@ -173,11 +166,12 @@ char const *accname[] = {"eses", "eseh", "es", "eh", "", string Pitch::to_string () const { - int n = (notename_ + 2) % scale_->step_semitones_.size (); + int n = (notename_ + 2) % scale_->step_tones_.size (); string s = ::to_string (char (n + 'a')); - if (alteration_) - s += string (accname[alteration_ - DOUBLE_FLAT]); - + Rational qtones = alteration_ * Rational (4,1); + int qt = int (rint (Real (qtones))); + + s += string (accname[qt + 4]); if (octave_ >= 0) { int o = octave_ + 1; @@ -294,7 +288,7 @@ Pitch::get_notename () const return notename_; } -int +Rational Pitch::get_alteration () const { return alteration_; @@ -307,3 +301,6 @@ Pitch::transposed (Pitch d) const p.transpose (d); return p; } + +Rational FLAT_ALTERATION (-1, 2); +Rational SHARP_ALTERATION (1, 2); diff --git a/lily/pitched-trill-engraver.cc b/lily/pitched-trill-engraver.cc index da74dafcdd..33bb1a8084 100644 --- a/lily/pitched-trill-engraver.cc +++ b/lily/pitched-trill-engraver.cc @@ -83,7 +83,7 @@ Pitched_trill_engraver::make_trill (Stream_event *ev) SCM handle = scm_assoc (key, keysig); bool print_acc - = (handle == SCM_BOOL_F) || p->get_alteration () == 0; + = (handle == SCM_BOOL_F) || p->get_alteration () == Rational (0); if (trill_head_) { @@ -110,7 +110,7 @@ Pitched_trill_engraver::make_trill (Stream_event *ev) trill_accidental_ = make_item ("TrillPitchAccidental", ev->self_scm ()); // fixme: naming -> alterations - trill_accidental_->set_property ("accidentals", scm_list_1 (scm_from_int (p->get_alteration ()))); + trill_accidental_->set_property ("accidentals", scm_list_1 (scm_from_int (p->rounded_quartertone_pitch ()))); Side_position_interface::add_support (trill_accidental_, trill_head_); trill_head_->set_object ("accidental-grob", trill_accidental_->self_scm ()); diff --git a/lily/relative-octave-check.cc b/lily/relative-octave-check.cc index 388e2f2d0f..cc1efe3d21 100644 --- a/lily/relative-octave-check.cc +++ b/lily/relative-octave-check.cc @@ -45,5 +45,6 @@ Relative_octave_check::relative_callback (SCM music, SCM last_pitch) } return Pitch (p.get_octave () + delta_oct, - p.get_notename (), p.get_alteration ()).smobbed_copy (); + p.get_notename (), + p.get_alteration ()).smobbed_copy (); } diff --git a/lily/scale.cc b/lily/scale.cc index b71f43fe20..89e8103887 100644 --- a/lily/scale.cc +++ b/lily/scale.cc @@ -7,35 +7,41 @@ */ -#include "pitch.hh" +#include "scale.hh" #include "ly-smobs.icc" +/* + todo: put string <-> pitch here too. + +*/ 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; + 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); + type_ok = type_ok && scm_is_rational (step); if (type_ok) - semitones.push_back (scm_to_int (step)); + { + Rational from_c (scm_to_int (scm_numerator (step)), + scm_to_int (scm_denominator (step))); + semitones.push_back (from_c); + } } } - SCM_ASSERT_TYPE (type_ok, steps, SCM_ARG1, __FUNCTION__, "vector of int"); - Scale *s = new Scale; - s->step_semitones_ = semitones; + s->step_tones_ = semitones; SCM retval = s->self_scm (); @@ -96,7 +102,7 @@ Scale::Scale () Scale::Scale (Scale const &src) { - step_semitones_ = src.step_semitones_; + step_tones_ = src.step_tones_; smobify_self (); } diff --git a/lily/tab-note-heads-engraver.cc b/lily/tab-note-heads-engraver.cc index a9e6556734..4fb33f7199 100644 --- a/lily/tab-note-heads-engraver.cc +++ b/lily/tab-note-heads-engraver.cc @@ -113,7 +113,7 @@ Tab_note_heads_engraver::process_music () while (!string_found) { - int fret = unsmob_pitch (scm_pitch)->semitone_pitch () + int fret = unsmob_pitch (scm_pitch)->rounded_semitone_pitch () - scm_to_int (scm_list_ref (string_tunings, scm_from_int (tab_string - 1))); if (fret < min_fret) tab_string += high_string_one ? 1 : -1; diff --git a/ly/engraver-init.ly b/ly/engraver-init.ly index f69cc77fbc..fc0b867e82 100644 --- a/ly/engraver-init.ly +++ b/ly/engraver-init.ly @@ -554,8 +554,8 @@ AncientRemoveEmptyStaffContext = \context { printKeyCancellation = ##t keyAlterationOrder = #`( (6 . ,FLAT) (2 . ,FLAT) (5 . ,FLAT ) (1 . ,FLAT) (4 . ,FLAT) (0 . ,FLAT) (3 . ,FLAT) - (3 . ,SHARP) (0 . ,SHARP) (4 . ,SHARP) (1 . ,SHARP) (5 . ,SHARP) (2 . ,SHARP) (6 . ,SHARP) - (6 . ,DOUBLE-FLAT) (2 . ,DOUBLE-FLAT) (5 . ,DOUBLE-FLAT ) (1 . ,DOUBLE-FLAT) (4 . ,DOUBLE-FLAT) (0 . ,DOUBLE-FLAT) (3 . ,DOUBLE-FLAT) + (3 . ,SHARP) (0 . ,SHARP) (4 . ,SHARP) (1 . ,SHARP) (5 . ,SHARP) (2 . ,SHARP) (6 . ,SHARP) + (6 . ,DOUBLE-FLAT) (2 . ,DOUBLE-FLAT) (5 . ,DOUBLE-FLAT ) (1 . ,DOUBLE-FLAT) (4 . ,DOUBLE-FLAT) (0 . ,DOUBLE-FLAT) (3 . ,DOUBLE-FLAT) (3 . ,DOUBLE-SHARP) (0 . ,DOUBLE-SHARP) (4 . ,DOUBLE-SHARP) (2 . ,DOUBLE-SHARP) (5 . ,DOUBLE-SHARP) (2 . ,DOUBLE-SHARP) (6 . ,DOUBLE-SHARP) ) diff --git a/scm/chord-entry.scm b/scm/chord-entry.scm index cf8ea886f2..1e3a034fd8 100644 --- a/scm/chord-entry.scm +++ b/scm/chord-entry.scm @@ -12,6 +12,7 @@ Notes: natural 11 is left from chord if not explicitly specified. Entry point for the parser. " + (display modifications) (let* ((flat-mods (flatten-list modifications)) (base-chord (stack-thirds (ly:make-pitch 0 4 0) the-canonical-chord)) (complete-chord '()) @@ -218,6 +219,7 @@ DURATION, and INVERSION." (map (lambda (n) (define (nca x) (if (= x 7) FLAT 0)) + (if (>= n 8) (ly:make-pitch 1 (- n 8) (nca n)) (ly:make-pitch 0 (- n 1) (nca n)))) diff --git a/scm/lily-library.scm b/scm/lily-library.scm index 0d09beae53..cb240332ca 100644 --- a/scm/lily-library.scm +++ b/scm/lily-library.scm @@ -19,16 +19,27 @@ (define-public DOWN -1) (define-public CENTER 0) -(define-safe-public DOUBLE-FLAT -4) -(define-safe-public THREE-Q-FLAT -3) -(define-safe-public FLAT -2) -(define-safe-public SEMI-FLAT -1) +(define-safe-public DOUBLE-FLAT-QTS -4) +(define-safe-public THREE-Q-FLAT-QTS -3) +(define-safe-public FLAT-QTS -2) +(define-safe-public SEMI-FLAT-QTS -1) +(define-safe-public NATURAL-QTS 0) +(define-safe-public SEMI-SHARP-QTS 1) +(define-safe-public SHARP-QTS 2) +(define-safe-public THREE-Q-SHARP-QTS 3) +(define-safe-public DOUBLE-SHARP-QTS 4) +(define-safe-public SEMI-TONE-QTS 2) + +(define-safe-public DOUBLE-FLAT -1) +(define-safe-public THREE-Q-FLAT -3/4) +(define-safe-public FLAT -1/2) +(define-safe-public SEMI-FLAT -1/4) (define-safe-public NATURAL 0) -(define-safe-public SEMI-SHARP 1) -(define-safe-public SHARP 2) -(define-safe-public THREE-Q-SHARP 3) -(define-safe-public DOUBLE-SHARP 4) -(define-safe-public SEMI-TONE 2) +(define-safe-public SEMI-SHARP 1/4) +(define-safe-public SHARP 1/2) +(define-safe-public THREE-Q-SHARP 3/4) +(define-safe-public DOUBLE-SHARP 1) +(define-safe-public SEMI-TONE 1/2) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; moments diff --git a/scm/lily.scm b/scm/lily.scm index e71d400859..78430f882e 100644 --- a/scm/lily.scm +++ b/scm/lily.scm @@ -254,7 +254,7 @@ The syntax is the same as `define*-public'." ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;; init pitch system -(ly:set-default-scale (ly:make-scale #(0 2 4 5 7 9 11))) +(ly:set-default-scale (ly:make-scale #(0 1 2 5/2 7/2 9/2 11/2))) -- 2.39.2