From fec655c6e4f5c3a4dac31f4bb30a244a547a8909 Mon Sep 17 00:00:00 2001 From: fred Date: Wed, 27 Mar 2002 00:33:15 +0000 Subject: [PATCH] lilypond-1.3.108 --- lily/chord.cc | 830 ++++++++++++++++++++++++-------------------------- 1 file changed, 398 insertions(+), 432 deletions(-) diff --git a/lily/chord.cc b/lily/chord.cc index 26602a5e78..6f4e565ace 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -13,315 +13,221 @@ #include "music-list.hh" #include "musical-request.hh" -/* - UGH - - should compare SCM lists. - */ -int -compare (Chord* left, Chord* right) -{ - assert (left); - assert (right); - - return !(left->inversion_b_ == right->inversion_b_ - && left->bass_b_ == right->bass_b_ - && !compare (&left->pitch_arr_, &right->pitch_arr_)); -} - -/* - FIXME: should use SCM iso. arrays and have-to-delete pointers. - - FIXME: a real function looks like - +/* some SCM abbrevs - Return_value func (Input_value), + zijn deze nou handig? + zijn ze er al in scheme, maar heten ze anders? */ - not - void func (Input_value *); - - FIXME: - - pitch is really a tuple, hence an immutable object. We - should remove all mutating operations. - - */ - -/* - construct from parser output -*/ -Chord -to_chord (Musical_pitch tonic, Array* add_arr_p, Array* sub_arr_p, Musical_pitch* inversion_p, Musical_pitch* bass_p) +/* Remove doubles from (sorted) list */ +SCM +ly_unique (SCM list) { - // urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered - bool dim_b = false; - for (int i=0; i < add_arr_p->size (); i++) + SCM unique = SCM_EOL; + for (SCM i = list; gh_pair_p (i); i = gh_cdr (i)) { - Musical_pitch* p = &(*add_arr_p)[i]; - if (p->octave_i () == -100) - { - p->octave_i_ = 0; - dim_b = true; - } + if (!gh_pair_p (gh_cdr (i)) + || !gh_equal_p (gh_car (i), gh_cadr (i))) + unique = gh_cons (gh_car (i), unique); } - Chord::rebuild_transpose (add_arr_p, tonic, true); - Chord::rebuild_transpose (sub_arr_p, tonic, true); - - Musical_pitch fifth = Chord::base_arr (tonic).top (); + return gh_reverse (unique); +} - /* - remove double adds (urg: sus4) - */ - for (int i = add_arr_p->size () - 1; i >= 0 ; i--) +/* Hmm, rewrite this using ly_split_list? */ +SCM +ly_remove_member (SCM s, SCM list) +{ + SCM removed = SCM_EOL; + for (SCM i = list; gh_pair_p (i); i = gh_cdr (i)) { - int j = Chord::find_pitch_i (add_arr_p, (*add_arr_p)[i]); - if ((j != -1) && (i != j)) - { - add_arr_p->get (i); - } + if (!gh_equal_p (gh_car (i), s)) + removed = gh_cons (gh_car (i), removed); } + return gh_reverse (removed); +} - /* - default chord includes upto 5: <1, 3, 5> - */ - add_arr_p->insert (tonic, 0); - Array tmp = *add_arr_p; - int highest_step = Chord::step_i (tonic, tmp.top ()); - if (highest_step < 5) - tmp.push (fifth); - else if (dim_b) - { - Musical_pitch* p = &add_arr_p->top (); - p->alteration_i_--; - } +SCM +ly_last (SCM list) +{ + return gh_car (scm_last_pair (list)); +} - /* - find missing thirds - */ - Array missing_arr = Chord::missing_thirds_pitch_arr (&tmp); - if (highest_step < 5) - missing_arr.push (fifth); +/* tail add */ +SCM +ly_snoc (SCM s, SCM list) +{ + return gh_append2 (list, gh_list (s, SCM_UNDEFINED)); +} - /* - if dim modifier is given: lower all missing - */ - if (dim_b) - { - for (int i=0; i < missing_arr.size (); i++) - { - missing_arr[i].alteration_i_--; - } - } - /* - if additions include some 3, don't add third - */ - Musical_pitch third = Chord::base_arr (tonic)[1]; - if (Chord::find_notename_i (add_arr_p, third) != -1) - { - int i = Chord::find_pitch_i (&missing_arr, third); - if (i != -1) - missing_arr.get (i); - } - - /* - if additions include 4, assume sus4 and don't add third implicitely - C-sus (4) = c f g (1 4 5) - */ - Musical_pitch sus = tonic; - sus.transpose (Musical_pitch (0,3,0)); - if (Chord::find_pitch_i (add_arr_p, sus) != -1) +/* Split list at member s, removing s. + Return (BEFORE . AFTER) */ +SCM +ly_split_list (SCM s, SCM list) +{ + SCM before = SCM_EOL; + SCM after = list; + for (; gh_pair_p (after);) { - int i = Chord::find_pitch_i (&missing_arr, third); - if (i != -1) - missing_arr.get (i); + SCM i = gh_car (after); + after = gh_cdr (after); + if (gh_equal_p (i, s)) + break; + before = gh_cons (i, before); } + return gh_cons (gh_reverse (before), after); +} - /* - if additions include some 5, don't add fifth - */ - if (Chord::find_notename_i (add_arr_p, fifth) != -1) - { - int i = Chord::find_pitch_i (&missing_arr, fifth); - if (i != -1) - missing_arr.get (i); - } - - - /* - complete the list of thirds to be added - */ - add_arr_p->concat (missing_arr); - add_arr_p->sort (Musical_pitch::compare); - - Array pitch_arr; - /* - add all that aren't subtracted - */ - for (int i = 0; i < add_arr_p->size (); i++) - { - Musical_pitch p = (*add_arr_p)[i]; - int j = 0; - for (; j < sub_arr_p->size (); j++) - if (p == (*sub_arr_p)[j]) - { - sub_arr_p->del (j); - j = -1; - break; - } - if (j == sub_arr_p->size ()) - pitch_arr.push (p); - } - pitch_arr.sort (Musical_pitch::compare); +/* Construct from list of pitches and requests: - for (int i = 0; i < sub_arr_p->size (); i++) - warning (_f ("invalid subtraction: not part of chord: %s", - (*sub_arr_p)[i].str ())); - - return Chord (pitch_arr, inversion_p, bass_p); -} + (PITCHES . (INVERSION . BASS)) -/* - Construct from list of pitches and requests - */ -Chord -to_chord (Array pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b) + + Note, the pitches here, are all inclusive. + We must identify tonic, filter-out (and maybe detect) inversion and bass. */ + +SCM +Chord::pitches_and_requests_to_chord (SCM pitches, + SCM tonic_req, + SCM inversion_req, + SCM bass_req, + bool find_inversion_b) { - Musical_pitch* inversion_p = 0; - Musical_pitch* bass_p = 0; + pitches = scm_sort_list (pitches, + scm_eval2 (ly_symbol2scm ("Pitch::less_p"), + SCM_EOL)); - if (bass_req) + + if (bass_req != SCM_EOL) { - assert (pitch_arr[0].notename_i_ == unsmob_pitch (bass_req->get_mus_property ("pitch"))->notename_i_); - bass_p = new Musical_pitch (pitch_arr.get (0)); + assert (unsmob_pitch (gh_car (pitches))->notename_i_ + == unsmob_pitch (bass_req)->notename_i_); + pitches = gh_cdr (pitches); } - if (inversion_req) + if (inversion_req != SCM_EOL) { - assert (pitch_arr[0].notename_i_ == unsmob_pitch (inversion_req->get_mus_property ("pitch"))->notename_i_); - inversion_p = new Musical_pitch (* unsmob_pitch (inversion_req->get_mus_property ("pitch"))); - assert (tonic_req); - int tonic_i = Chord::find_notename_i (&pitch_arr, - *unsmob_pitch (tonic_req->get_mus_property ("pitch"))); - if (tonic_i) - Chord::rebuild_insert_inversion (&pitch_arr, tonic_i); + assert (unsmob_pitch (gh_car (pitches))->notename_i_ + == unsmob_pitch (inversion_req)->notename_i_); + /* huh ? */ + assert (tonic_req != SCM_EOL); + + SCM tonic = member_notename (tonic_req, pitches); + if (tonic != SCM_EOL) + pitches = rebuild_insert_inversion (pitches); //, tonic); } - - if (find_inversion_b && !inversion_p) + else if (find_inversion_b) { - int tonic_i = tonic_req - ? Chord::find_notename_i (&pitch_arr, *unsmob_pitch (tonic_req->get_mus_property ("pitch"))) - : Chord::find_tonic_i (&pitch_arr); + SCM tonic = (tonic_req != SCM_EOL) + ? member_notename (pitches, tonic_req) + : guess_tonic (pitches); - if (tonic_i) + if (tonic != SCM_EOL) { - inversion_p = &pitch_arr[0]; - Chord::rebuild_insert_inversion (&pitch_arr, tonic_i); + inversion_req = gh_car (pitches); + pitches = rebuild_insert_inversion (pitches); //, tonic); } } - if (tonic_req) - { - assert (pitch_arr[0].notename_i_ == unsmob_pitch (tonic_req->get_mus_property ("pitch"))->notename_i_); - } - - return Chord (pitch_arr, inversion_p, bass_p); -} + if (tonic_req != SCM_EOL) + assert (unsmob_pitch (gh_car (pitches))->notename_i_ + == unsmob_pitch (tonic_req)->notename_i_); -Chord::Chord () -{ - inversion_b_ = false; - bass_b_ = false; + return gh_cons (pitches, gh_cons (inversion_req, bass_req)); } -Chord::Chord (Array pitch_arr, Musical_pitch* inversion_p, Musical_pitch* bass_p) -{ - pitch_arr_ = pitch_arr; - inversion_b_ = false; - bass_b_ = false; - if (inversion_p) - { - inversion_pitch_ = *inversion_p; - inversion_b_ = true; - } - if (bass_p) - { - bass_pitch_ = *bass_p; - bass_b_ = true; - } -} - -Chord::Chord (Chord const& chord) -{ - pitch_arr_ = chord.pitch_arr_; - inversion_b_ = chord.inversion_b_; - inversion_pitch_ = chord.inversion_pitch_; - bass_b_ = chord.bass_b_; - bass_pitch_ = chord.bass_pitch_; -} - - /* JUNKME. do something smarter. + zoals? */ -Array -Chord::base_arr (Musical_pitch p) +SCM +Chord::base_pitches (SCM tonic) { - Array base; - base.push (p); - p.transpose (Musical_pitch (0,2,0)); - base.push (p); - p.transpose (Musical_pitch (0, 2, -1)); - base.push (p); - return base; + SCM base = SCM_EOL; + + SCM major = Pitch (0, 2, 0).smobbed_copy (); + SCM minor = Pitch (0, 2, -1).smobbed_copy (); + + base = gh_cons (tonic, base); + base = gh_cons (Pitch::transpose (gh_car (base), major), base); + base = gh_cons (Pitch::transpose (gh_car (base), minor), base); + + return gh_reverse (base); } -void -Chord::rebuild_transpose (Array* pitch_arr_p, Musical_pitch tonic, bool fix7_b) +SCM +Chord::transpose_pitches (SCM tonic, SCM pitches) { - for (int i = 0; i < pitch_arr_p->size (); i++) + /* map? + hoe doe je lambda in C? + */ + SCM transposed = SCM_EOL; + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) { - Musical_pitch p = tonic; - Musical_pitch q = (*pitch_arr_p)[i]; - p.transpose (q); - // duh, c7 should mean - if (fix7_b && (step_i (tonic, p) == 7)) - p.alteration_i_--; - (*pitch_arr_p)[i] = p; + transposed = gh_cons (Pitch::transpose (tonic, gh_car (i)), + transposed); } - pitch_arr_p->sort (Musical_pitch::compare); + return gh_reverse (transposed); } -int -Chord::find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) +/* + burp, in SCM duw je gewoon een (if (= (step x) 7) (...)) door pitches + + Lower step STEP. + If step == 0, lower all. + */ +SCM +Chord::lower_step (SCM tonic, SCM pitches, SCM step) { - for (int i = 0; i < pitch_arr_p->size (); i++) - if (p == (*pitch_arr_p)[i]) - return i; - return -1; + SCM lowered = SCM_EOL; + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) + { + SCM p = gh_car (i); + if (gh_equal_p (step_scm (tonic, gh_car (i)), step) + || gh_scm2int (step) == 0) + { +#if 0 + Pitch x = *unsmob_pitch (p); + x.alteration_i_--; + p = x.smobbed_copy (); +#else + p = Pitch::transpose (p, Pitch (0, 0, -1).smobbed_copy ()); +#endif + } + lowered = gh_cons (p, lowered); + } + return gh_reverse (lowered); } -int -Chord::find_notename_i (Array const* pitch_arr_p, Musical_pitch p) +/* Return member that has same notename, disregarding octave or accidentals */ +SCM +Chord::member_notename (SCM p, SCM pitches) { - int i = find_pitch_i (pitch_arr_p, p); - if (i == -1) + /* If there's an exact match, make sure to return that */ + SCM member = gh_member (p, pitches); + if (member == SCM_BOOL_F) { - for (int i = 0; i < pitch_arr_p->size (); i++) + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) { - p.octave_i_ = (*pitch_arr_p)[i].octave_i () ; - if (p == (*pitch_arr_p)[i]) - return i; + /* + Urg, eindelijk gevonden: () != #f, kan maar niet aan wennen. + Anders kon iets korter... + */ + if (unsmob_pitch (p)->notename_i_ + == unsmob_pitch (gh_car (i))->notename_i_) + { + member = gh_car (i); + break; + } } } - return i; + return member; } int -Chord::step_i (Musical_pitch tonic, Musical_pitch p) +Chord::step_i (Pitch tonic, Pitch p) { int i = p.notename_i_ - tonic.notename_i_ + (p.octave_i () - tonic.octave_i () ) * 7; @@ -331,90 +237,105 @@ Chord::step_i (Musical_pitch tonic, Musical_pitch p) return i; } +SCM +Chord::step_scm (SCM tonic, SCM p) +{ + return gh_int2scm (step_i (*unsmob_pitch (tonic), *unsmob_pitch (p))); +} + /* - JUNKME. - do something smarter. + docme */ -Array -Chord::missing_thirds_pitch_arr (Array const* pitch_arr_p) +SCM +Chord::missing_thirds (SCM pitches) { - Array thirds; - + SCM thirds = SCM_EOL; + /* is the third c-e, d-f, etc. small or large? */ - int minormajor_a[] = {0, -1, -1, 0,0,-1,-1}; + int minormajor_a[] = {0, -1, -1, 0, 0, -1, -1}; for (int i=0; i < 7; i++) - thirds.push (Musical_pitch( 0, 2, minormajor_a[i])); - - Musical_pitch tonic = (*pitch_arr_p)[0]; - Musical_pitch last = tonic; - Array missing_arr; + thirds = gh_cons (Pitch (0, 2, minormajor_a[i]).smobbed_copy (), + thirds); + thirds = scm_vector (gh_reverse (thirds)); + + SCM tonic = gh_car (pitches); + SCM last = tonic; + SCM missing = SCM_EOL; - for (int i = 0; i < pitch_arr_p->size ();) + for (SCM i = pitches; gh_pair_p (i);) { - Musical_pitch p = (*pitch_arr_p)[i]; - int step = step_i (tonic, p); - if (last.notename_i_ == p.notename_i_) - last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); - if (step > step_i (tonic, last)) + SCM p = gh_car (i); + int step = gh_scm2int (step_scm (tonic, p)); + + if (unsmob_pitch (last)->notename_i_ == unsmob_pitch (p)->notename_i_) + { + int third = (unsmob_pitch (last)->notename_i_ + - unsmob_pitch (tonic)-> notename_i_ + 7) % 7; + last = Pitch::transpose (last, scm_vector_ref (thirds, gh_int2scm (third))); + } + + if (step > gh_scm2int (step_scm (tonic, last))) { - while (step > step_i (tonic, last)) + while (step > gh_scm2int (step_scm (tonic, last))) { - if ((last.notename_i_ - tonic.notename_i_ + 7) % 7 == 6) - { - Musical_pitch special_seven = last; - Musical_pitch lower (0, 0, -1); - special_seven.transpose (lower); - missing_arr.push (special_seven); - } - else - { - missing_arr.push (last); - } - last.transpose (thirds[(last.notename_i_ - tonic.notename_i_ + 7) % 7]); + missing = gh_cons (last, missing); + int third = (unsmob_pitch (last)->notename_i_ + - unsmob_pitch (tonic)->notename_i_ + 7) % 7; + last = Pitch::transpose (last, scm_vector_ref (thirds, + gh_int2scm (third))); } } else { - i++; + i = gh_cdr (i); } } - return missing_arr; + + return lower_step (tonic, missing, gh_int2scm (7)); } /* - Mangle into list of pitches. + Mangle + + (PITCHES . (INVERSION . BASS)) + + into list of pitches. + For normal chord entry, inversion and bass pitches are retained in - specific *_requests - */ -Array -Chord::to_pitch_arr () const + specific *_requests */ + +SCM +Chord::to_pitches (SCM chord) { - Array pitch_arr = pitch_arr_; - if (inversion_b_) + SCM pitches = gh_car (chord); + SCM modifiers = gh_cdr (chord); + SCM inversion = gh_car (modifiers); + SCM bass = gh_cdr (modifiers); + if (inversion != SCM_EOL) { - int i = 0; - for (; i < pitch_arr.size (); i++) + Pitch inversion_pitch = *unsmob_pitch (inversion); + SCM i = pitches; + for (; gh_pair_p (i); i = gh_cdr (i)) { - if ((pitch_arr[i].notename_i_ == inversion_pitch_.notename_i_) - && (pitch_arr[i].alteration_i_ == inversion_pitch_.alteration_i_)) + Pitch p = *unsmob_pitch (gh_car (i)); + if ((p.notename_i_ == inversion_pitch.notename_i_) + && (p.alteration_i_ == inversion_pitch.alteration_i_)) break; } - if (i == pitch_arr.size ()) - { - warning (_f ("invalid inversion pitch: not part of chord: %s", - inversion_pitch_.str ())); - } + if (gh_pair_p (i)) + pitches = rebuild_with_bass (pitches, gh_car (i)); else - rebuild_with_bass (&pitch_arr, i); + warning (_f ("invalid inversion pitch: not part of chord: %s", + unsmob_pitch (inversion)->str ())); } - if (bass_b_) + if (bass != SCM_EOL) { - pitch_arr.insert (bass_pitch_, 0); - rebuild_with_bass (&pitch_arr, 0); + pitches = gh_cons (bass, pitches); + pitches = rebuild_with_bass (pitches, bass); } - return pitch_arr; + return pitches; } /* @@ -423,179 +344,224 @@ Chord::to_pitch_arr () const This is only used for chords that are entered as simultaneous notes, chords entered in \chord mode are fully defined. */ -int -Chord::find_tonic_i (Array const* pitch_arr_p) -{ - /* - find tonic - - first try: base of longest line of thirds - */ - int tonic_i = 0; - int longest_i = 0; - for (int i = 0; i < pitch_arr_p->size (); i++) - { - int no_third_i = 0; - int last_i = (*pitch_arr_p)[i % pitch_arr_p->size ()].notename_i_; - int j = 0; - for (; j < pitch_arr_p->size (); j++) - { - int cur_i = (*pitch_arr_p)[(i + j + 1) % pitch_arr_p->size ()].notename_i_; - int gap = cur_i - last_i; - while (gap < 0) - gap += 7; - gap %= 7; - if (gap == 2) - last_i = cur_i; - else - no_third_i++; - } - if (j - no_third_i > longest_i) - { - longest_i = j - no_third_i; - tonic_i = i; - } - } - /* - second try: note after biggest gap - */ - int biggest_i = 0; - // if (longest_i) - if (longest_i <= 1) - for (int i = 0; i < pitch_arr_p->size (); i++) - { - int gap = (*pitch_arr_p)[i].notename_i_ - - (*pitch_arr_p)[(i - 1 + pitch_arr_p->size ()) - % pitch_arr_p->size ()].notename_i_; - while (gap < 0) - gap += 7; - gap %= 7; - if (gap > biggest_i) - { - biggest_i = gap; - tonic_i = i; - } - } - return tonic_i; -} +SCM +Chord::guess_tonic (SCM pitches) +{ + return gh_car (scm_sort_list (pitches, Pitch::less_p_proc)); +} -void -Chord::rebuild_from_base (Array* pitch_arr_p, int base_i) +SCM +Chord::rebuild_from_base (SCM pitches, SCM base) { - assert (base_i >= 0); - Musical_pitch last (0, 0, -5); - Array new_arr; - for (int i = 0; i < pitch_arr_p->size (); i++) + SCM split = ly_split_list (base, pitches); + SCM before = gh_car (split); + SCM after = gh_cdr (split); + + SCM last = Pitch (0, 0, -5).smobbed_copy (); + SCM rebuilt = SCM_EOL; + rebuilt = gh_cons (base, rebuilt); + for (SCM i = gh_append2 (after, before); gh_pair_p (i); i = gh_cdr (i)) { - Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()]; - if (p < last) + SCM p = gh_car (i); + if (Pitch::less_p (p, last) == SCM_BOOL_T) { - p.octave_i_ = last.octave_i () ; - if (p < last) - p.octave_i_++; + // UHUHUrg + p = Pitch (unsmob_pitch (last)->octave_i_, + unsmob_pitch (p)->notename_i_, + unsmob_pitch (p)->alteration_i_).smobbed_copy (); + if (Pitch::less_p (p, last)) + p = Pitch::transpose (p, Pitch (1, 0, 0).smobbed_copy ()); } - new_arr.push (p); + rebuilt = gh_cons (p, rebuilt); last = p; } - *pitch_arr_p = new_arr; + + return gh_reverse (rebuilt); } -void -Chord::rebuild_insert_inversion (Array* pitch_arr_p, int tonic_i) +SCM +Chord::rebuild_insert_inversion (SCM pitches) //, SCM tonic) { - assert (tonic_i > 0); - Musical_pitch inversion = pitch_arr_p->get (0); - rebuild_from_base (pitch_arr_p, tonic_i - 1); - if (pitch_arr_p->size ()) + SCM inversion = gh_car (pitches); + pitches = gh_cdr (pitches); + SCM tonic = gh_car (pitches); + pitches = rebuild_from_base (pitches, tonic); + if (pitches != SCM_EOL) { - inversion.octave_i_ = (*pitch_arr_p)[0].octave_i () - 1; - while (inversion < (*pitch_arr_p)[0]) - inversion.octave_i_++; + // UHUHUrg + inversion = Pitch (unsmob_pitch (gh_car (pitches))->octave_i_-1, + unsmob_pitch (inversion)->notename_i_, + unsmob_pitch (inversion)->alteration_i_).smobbed_copy (); + while (Pitch::less_p (inversion, gh_car (pitches)) == SCM_BOOL_T) + inversion = Pitch::transpose (inversion, Pitch (1, 0, 0).smobbed_copy ()); } - for (int i = 0; i < pitch_arr_p->size (); i++) - if ((*pitch_arr_p)[i] > inversion) - { - pitch_arr_p->insert (inversion, i); - break; - } + pitches = gh_cons (inversion, pitches); + return scm_sort_list (pitches, + scm_eval2 (ly_symbol2scm ("Pitch::less_p"), + SCM_EOL)); } -void -Chord::rebuild_with_bass (Array* pitch_arr_p, int bass_i) +SCM +Chord::rebuild_with_bass (SCM pitches, SCM bass) { - assert (bass_i >= 0); - Musical_pitch bass = pitch_arr_p->get (bass_i); + pitches = ly_remove_member (bass, pitches); // is lowering fine, or should others be raised? - if (pitch_arr_p->size ()) - while (bass > (*pitch_arr_p)[0]) - bass.octave_i_--; - pitch_arr_p->insert (bass, 0); + if (pitches != SCM_EOL) + while (Pitch::less_p (gh_car (pitches), bass) == SCM_BOOL_T) + bass = Pitch::transpose (bass, Pitch (-1, 0, 0).smobbed_copy ()); + return gh_cons (bass, pitches); } -// junk me -Simultaneous_music * -get_chord (SCM stonic, - SCM sadd_arr_p, - SCM ssub_arr_p, - SCM sinversion_p, - SCM sbass_p, - SCM dur) + +/*********************************/ +/* Parser stuff */ + +/* Construct from parser output: + + (PITCHES . (INVERSION . BASS)) */ +SCM +Chord::tonic_add_sub_inversion_bass_to_scm (SCM tonic, SCM add, SCM sub, + SCM inversion, SCM bass) { - Musical_pitch tonic = *unsmob_pitch (stonic); + SCM less = scm_eval2 (ly_symbol2scm ("Pitch::less_p"), SCM_EOL); + + /* urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered */ + bool dim_b = false; + for (SCM i = add; gh_pair_p (i); i = gh_cdr (i)) + { + Pitch* p = unsmob_pitch (gh_car (i)); + if (p->octave_i () == -100) + { + p->octave_i_ = 0; + dim_b = true; + } + } + add = transpose_pitches (tonic, add); + add = lower_step (tonic, add, gh_int2scm (7)); + add = scm_sort_list (add, less); + add = ly_unique (add); - Musical_pitch *inversion_p = unsmob_pitch( sinversion_p); - Musical_pitch *bass_p = unsmob_pitch (sbass_p); - - Array add_arr_p; - Array sub_arr_p; + sub = transpose_pitches (tonic, sub); + sub = lower_step (tonic, sub, gh_int2scm (7)); + sub = scm_sort_list (sub, less); + + /* default chord includes upto 5: <1, 3, 5> */ + add = gh_cons (tonic, add); + SCM tmp = add; + + SCM fifth = ly_last (base_pitches (tonic)); + int highest_step = gh_scm2int (step_scm (tonic, ly_last (tmp))); + if (highest_step < 5) + tmp = ly_snoc (fifth, tmp); + else if (dim_b) + add = lower_step (tonic, add, gh_int2scm (5)); + + /* find missing thirds */ + SCM missing = missing_thirds (tmp); + if (highest_step < 5) + missing = ly_snoc (fifth, missing); - for (SCM s = sadd_arr_p ; gh_pair_p (s); s = gh_cdr (s)) - add_arr_p.push (*unsmob_pitch (gh_car (s))); - for (SCM s = ssub_arr_p ; gh_pair_p (s); s = gh_cdr (s)) - sub_arr_p.push (*unsmob_pitch (gh_car (s))); + /* if dim modifier is given: lower all missing */ + if (dim_b) + missing = lower_step (tonic, missing, gh_int2scm (0)); + + /* if additions include any 3, don't add third */ + SCM third = gh_cadr (base_pitches (tonic)); + if (member_notename (third, add) != SCM_BOOL_F) + missing = ly_remove_member (third, missing); + + /* if additions include any 4, assume sus4 and don't add third implicitely + C-sus (4) = c f g (1 4 5) */ + SCM sus = Pitch::transpose (tonic, Pitch (0, 3, 0).smobbed_copy ()); + if (member_notename (sus, add) != SCM_BOOL_F) + missing = ly_remove_member (third, missing); + + /* if additions include some 5, don't add fifth */ + if (member_notename (fifth, add) != SCM_BOOL_F) + missing = ly_remove_member (fifth, missing); + + /* complete the list of thirds to be added */ + add = gh_append2 (missing, add); + add = scm_sort_list (add, less); - sub_arr_p.reverse (); - add_arr_p.reverse (); + SCM pitches = SCM_EOL; + /* Add all that aren't subtracted */ + for (SCM i = add; gh_pair_p (i); i = gh_cdr (i)) + { + SCM p = gh_car (i); + SCM s = member_notename (p, sub); + if (s != SCM_BOOL_F) + sub = ly_remove_member (s, sub); + else + pitches = gh_cons (p, pitches); + } + pitches = scm_sort_list (pitches, less); + + for (SCM i = sub; gh_pair_p (i); i = gh_cdr (i)) + warning (_f ("invalid subtraction: not part of chord: %s", + unsmob_pitch (gh_car (i))->str ())); - /* - UARGAUGRAGRUAUGRUINAGRAUGIRNA + return gh_cons (pitches, gh_cons (inversion, bass)); +} - ugh - */ - Chord chord = to_chord (tonic, &add_arr_p, &sub_arr_p, inversion_p, bass_p); - inversion_p = 0; - bass_p = 0; +/* + junk me + + snapnie + + Een chord invoer bestaat uit een naam. Maar, we willen een aantal + pitch-requests doen, zodat na het parsen van een chord geen verschil + meer is met een gewoon accoord. Die vertaalslag is behoorlijk + harig, hoe wil je dit junken? Nouja, cleanup lijkt me aardige + eerste stap enniewee. + + + --Het lijkt me dat dit in het paarse gedeelte moet. + + Zo-en-zo, lijktme dat je ipv. Inversion_req een (inversion . #t) aan + de betreffende Noot_req kan hangen +*/ + +Simultaneous_music * +Chord::get_chord (SCM tonic, SCM add, SCM sub, SCM inversion, SCM bass, SCM dur) +{ + SCM chord = tonic_add_sub_inversion_bass_to_scm (tonic, add, sub, + inversion, bass); + Tonic_req* t = new Tonic_req; - t->set_mus_property ("pitch", tonic.smobbed_copy ()); + t->set_mus_property ("pitch", tonic); SCM l = gh_cons (t->self_scm (), SCM_EOL); + SCM modifiers = gh_cdr (chord); + inversion = gh_car (modifiers); + bass = gh_cdr (modifiers); + //urg - if (chord.inversion_b_ - && Chord::find_notename_i (&chord.pitch_arr_, chord.inversion_pitch_) > 0) + if (inversion != SCM_EOL) { Inversion_req* i = new Inversion_req; - i->set_mus_property ("pitch", chord.inversion_pitch_.smobbed_copy ()); + i->set_mus_property ("pitch", inversion); l = gh_cons (i->self_scm (), l); scm_unprotect_object (i->self_scm ()); } - if (chord.bass_b_) + if (bass != SCM_EOL) { Bass_req* b = new Bass_req; - b->set_mus_property ("pitch", chord.bass_pitch_.smobbed_copy ()); + b->set_mus_property ("pitch", bass); l = gh_cons (b->self_scm (), l); scm_unprotect_object (b->self_scm ()); } - Array pitch_arr = chord.to_pitch_arr (); - for (int i = pitch_arr.size (); --i >= 0;) + SCM pitches = Chord::to_pitches (chord); + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) { Note_req* n = new Note_req; - n->set_mus_property ("pitch", pitch_arr[i].smobbed_copy ()); + n->set_mus_property ("pitch", gh_car (i)); n->set_mus_property ("duration", dur); l = gh_cons (n->self_scm (), l); -- 2.39.5