X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=lily%2Fchord.cc;h=32215b656c157555d6fb6a4f05b96283c2fbe7ad;hb=fb1afe411d7ef4d5c8853c936adf894e3edbf833;hp=8a524f0110d163dd30079599c04e6820aa8e8dc9;hpb=8903693f3b43cf4b196b558aa939b9e148ddaec1;p=lilypond.git diff --git a/lily/chord.cc b/lily/chord.cc index 8a524f0110..32215b656c 100644 --- a/lily/chord.cc +++ b/lily/chord.cc @@ -3,497 +3,426 @@ source file of the GNU LilyPond music typesetter - (c) 1999--2000 Jan Nieuwenhuizen + (c) 1999--2001 Jan Nieuwenhuizen */ #include "chord.hh" #include "musical-request.hh" #include "warn.hh" #include "debug.hh" -#include "molecule.hh" -#include "paper-def.hh" -#include "lookup.hh" +#include "music-list.hh" +#include "musical-request.hh" +/* some SCM abbrevs -/* - 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) -{ - // urg: catch dim modifier: 3rd, 5th, 7th, .. should be lowered - bool dim_b = false; - for (int i=0; i < add_arr_p->size (); i++) - { - Musical_pitch* p = &(*add_arr_p)[i]; - if (p->octave_i_ == -100) - { - p->octave_i_ = 0; - dim_b = true; - } - } - Chord::rebuild_transpose (add_arr_p, tonic, true); - Chord::rebuild_transpose (sub_arr_p, tonic, true); + zijn deze nou handig? + zijn ze er al in scheme, maar heten ze anders? */ - Musical_pitch fifth = Chord::base_arr (tonic).top (); - /* - remove double adds (urg: sus4) - */ - for (int i = add_arr_p->size () - 1; i >= 0 ; i--) +/* Remove doubles from (sorted) list */ +SCM +ly_unique (SCM list) +{ + SCM unique = 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_pair_p (gh_cdr (i)) + || !gh_equal_p (gh_car (i), gh_cadr (i))) + unique = gh_cons (gh_car (i), unique); } + return gh_reverse (unique); +} - /* - 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) +/* 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)) { - Musical_pitch* p = &add_arr_p->top (); - p->accidental_i_--; + if (!gh_equal_p (gh_car (i), s)) + removed = gh_cons (gh_car (i), removed); } + return gh_reverse (removed); +} - /* - find missing thirds - */ - Array missing_arr = Chord::missing_thirds_pitch_arr (&tmp); - if (highest_step < 5) - missing_arr.push (fifth); - - /* - if dim modifier is given: lower all missing - */ - if (dim_b) - { - for (int i=0; i < missing_arr.size (); i++) - { - missing_arr[i].accidental_i_--; - } - } +/* tail add */ +SCM +ly_snoc (SCM s, SCM list) +{ + return gh_append2 (list, gh_list (s, SCM_UNDEFINED)); +} - /* - 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 (3)); - if (Chord::find_pitch_i (add_arr_p, sus) != -1) - { - int i = Chord::find_pitch_i (&missing_arr, third); - if (i != -1) - missing_arr.get (i); - } - /* - 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++) +/* 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);) { - 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); + SCM i = gh_car (after); + after = gh_cdr (after); + if (gh_equal_p (i, s)) + break; + before = gh_cons (i, before); } - - pitch_arr.sort (Musical_pitch::compare); - - 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); + return gh_cons (gh_reverse (before), after); } /* - Construct from list of pitches and requests + JUNKME. + do something smarter. + zoals? */ -Chord -to_chord (Array pitch_arr, Tonic_req* tonic_req, Inversion_req* inversion_req, Bass_req* bass_req, bool find_inversion_b) +SCM +Chord::base_pitches (SCM tonic) { - Musical_pitch* inversion_p = 0; - Musical_pitch* bass_p = 0; + SCM base = SCM_EOL; - if (bass_req) - { - assert (pitch_arr[0].notename_i_ == bass_req->pitch_.notename_i_); - bass_p = new Musical_pitch (pitch_arr.get (0)); - } - - if (inversion_req) - { - assert (pitch_arr[0].notename_i_ == inversion_req->pitch_.notename_i_); - inversion_p = new Musical_pitch (inversion_req->pitch_); - assert (tonic_req); - int tonic_i = Chord::find_notename_i (&pitch_arr, tonic_req->pitch_); - if (tonic_i) - Chord::rebuild_insert_inversion (&pitch_arr, tonic_i); - } - - if (find_inversion_b && !inversion_p) - { - int tonic_i = tonic_req - ? Chord::find_notename_i (&pitch_arr, tonic_req->pitch_) - : Chord::find_tonic_i (&pitch_arr); - - if (tonic_i) - { - inversion_p = &pitch_arr[0]; - Chord::rebuild_insert_inversion (&pitch_arr, tonic_i); - } - } + SCM major = Pitch (0, 2, 0).smobbed_copy (); + SCM minor = Pitch (0, 2, -1).smobbed_copy (); - if (tonic_req) - { - assert (pitch_arr[0].notename_i_ == tonic_req->pitch_.notename_i_); - } + 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 Chord (pitch_arr, inversion_p, bass_p); + return gh_reverse (base); } -Chord::Chord () +SCM +Chord::transpose_pitches (SCM tonic, SCM pitches) { - inversion_b_ = false; - bass_b_ = false; -} - -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) + /* map? + hoe doe je lambda in C? + */ + SCM transposed = SCM_EOL; + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) { - inversion_pitch_ = *inversion_p; - inversion_b_ = true; - delete inversion_p; - } - if (bass_p) - { - bass_pitch_ = *bass_p; - bass_b_ = true; - delete bass_p; + transposed = gh_cons (Pitch::transpose (tonic, gh_car (i)), + transposed); } + return gh_reverse (transposed); } - -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_; -} - -Array -Chord::base_arr (Musical_pitch p) -{ - Array base; - base.push (p); - p.transpose (Musical_pitch (2)); - base.push (p); - p.transpose (Musical_pitch (2, -1)); - base.push (p); - return base; -} +/* + burp, in SCM duw je gewoon een (if (= (step x) 7) (...)) door pitches -void -Chord::rebuild_transpose (Array* pitch_arr_p, Musical_pitch tonic, bool fix7_b) + 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++) + SCM lowered = 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.accidental_i_--; - (*pitch_arr_p)[i] = p; + SCM p = gh_car (i); + if (gh_equal_p (step_scm (tonic, gh_car (i)), step) + || gh_scm2int (step) == 0) + { + p = Pitch::transpose (p, Pitch (0, 0, -1).smobbed_copy ()); + } + lowered = gh_cons (p, lowered); } - pitch_arr_p->sort (Musical_pitch::compare); + return gh_reverse (lowered); } -int -Chord::find_pitch_i (Array const* pitch_arr_p, Musical_pitch p) +/* Return member that has same notename, disregarding octave or alterations */ +SCM +Chord::member_notename (SCM p, SCM pitches) { - for (int i = 0; i < pitch_arr_p->size (); i++) - if (p == (*pitch_arr_p)[i]) - return i; - return -1; + /* If there's an exact match, make sure to return that */ + SCM member = gh_member (p, pitches); + if (member == SCM_BOOL_F) + { + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (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; + } + } + } + else + member = gh_car (member); + return member; } -int -Chord::find_notename_i (Array const* pitch_arr_p, Musical_pitch p) +/* Return member that has same notename and alteration, disregarding octave */ +SCM +Chord::member_pitch (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; + if (unsmob_pitch (p)->notename_i_ + == unsmob_pitch (gh_car (i))->notename_i_ + && unsmob_pitch (p)->alteration_i_ + == unsmob_pitch (gh_car (i))->alteration_i_) + { + member = gh_car (i); + break; + } } } - return i; + else + member = gh_car (member); + return member; } -int -Chord::step_i (Musical_pitch tonic, Musical_pitch p) +SCM +Chord::step_scm (SCM tonic, SCM p) { - int i = p.notename_i_ - tonic.notename_i_ - + (p.octave_i_ - tonic.octave_i_) * 7; + /* De Pitch intervaas is nog beetje sleutelgat? */ + int i = unsmob_pitch (p)->notename_i_ + - unsmob_pitch (tonic)->notename_i_ + + (unsmob_pitch (p)->octave_i_ + - unsmob_pitch (tonic)->octave_i_ ) * 7; while (i < 0) i += 7; i++; - return i; + return gh_int2scm (i); } /* - JUNKME. - do something smarter. - */ -Array -Chord::missing_thirds_pitch_arr (Array const* pitch_arr_p) -{ - Array thirds; + Assuming that PITCHES is a chord, with tonic (CAR PITCHES), find + missing thirds, only considering notenames. Eg, for + PITCHES = c gis d' + + return + + MISSING = e b' + +*/ +SCM +Chord::missing_thirds (SCM pitches) +{ + 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( 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, -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)); } +/* Return PITCHES with PITCH added not as lowest note */ +SCM +Chord::add_above_tonic (SCM pitch, SCM pitches) +{ + /* Should we maybe first make sure that PITCH is below tonic? */ + if (pitches != SCM_EOL) + while (Pitch::less_p (pitch, gh_car (pitches)) == SCM_BOOL_T) + pitch = Pitch::transpose (pitch, Pitch (1, 0, 0).smobbed_copy ()); + + pitches = gh_cons (pitch, pitches); + return scm_sort_list (pitches, Pitch::less_p_proc); +} + +/* Return PITCHES with PITCH added as lowest note */ +SCM +Chord::add_below_tonic (SCM pitch, SCM pitches) +{ + if (pitches != SCM_EOL) + while (Pitch::less_p (gh_car (pitches), pitch) == SCM_BOOL_T) + pitch = Pitch::transpose (pitch, Pitch (-1, 0, 0).smobbed_copy ()); + return gh_cons (pitch, pitches); +} + + /* - Mangle into list of pitches. - For normal chord entry, inversion and bass pitches are retained in - specific *_requests - */ -Array -Chord::to_pitch_arr () const + Parser stuff + + Construct from parser output: + + PITCHES is the plain chord, it does not include bass or inversion + + Part of Chord:: namespace for now, because we do lots of + chord-manipulating stuff. +*/ +SCM +Chord::tonic_add_sub_to_pitches (SCM tonic, SCM add, SCM sub) { - Array pitch_arr = pitch_arr_; - if (inversion_b_) + /* 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)) { - int i = 0; - for (; i < pitch_arr.size (); i++) - { - if ((pitch_arr[i].notename_i_ == inversion_pitch_.notename_i_) - && (pitch_arr[i].accidental_i_ == inversion_pitch_.accidental_i_)) - break; - } - if (i == pitch_arr.size ()) - { - warning (_f ("invalid inversion pitch: not part of chord: %s", - inversion_pitch_.str ())); + Pitch* p = unsmob_pitch (gh_car (i)); + if (p->octave_i () == -100) + { + p->octave_i_ = 0; + dim_b = true; } - else - rebuild_with_bass (&pitch_arr, i); } + add = transpose_pitches (tonic, add); + add = lower_step (tonic, add, gh_int2scm (7)); + add = scm_sort_list (add, Pitch::less_p_proc); + add = ly_unique (add); + + sub = transpose_pitches (tonic, sub); + sub = lower_step (tonic, sub, gh_int2scm (7)); + sub = scm_sort_list (sub, Pitch::less_p_proc); + + /* 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)); - if (bass_b_) - { - pitch_arr.insert (bass_pitch_, 0); - rebuild_with_bass (&pitch_arr, 0); - } - return pitch_arr; -} + /* find missing thirds */ + SCM missing = missing_thirds (tmp); + if (highest_step < 5) + missing = ly_snoc (fifth, missing); -/* - This routine tries to guess tonic in a possibly inversed chord, ie - should produce: C. - 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 + /* 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 = scm_delete (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 = scm_delete (third, missing); + + /* if additions include some 5, don't add fifth */ + if (member_notename (fifth, add) != SCM_BOOL_F) + missing = scm_delete (fifth, missing); - 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++) + /* complete the list of thirds to be added */ + add = gh_append2 (missing, add); + add = scm_sort_list (add, Pitch::less_p_proc); + + SCM pitches = SCM_EOL; + /* Add all that aren't subtracted */ + for (SCM i = add; gh_pair_p (i); i = gh_cdr (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; - } + SCM p = gh_car (i); + SCM s = member_notename (p, sub); + if (s != SCM_BOOL_F) + sub = scm_delete (s, sub); + else + pitches = gh_cons (p, pitches); } + pitches = scm_sort_list (pitches, Pitch::less_p_proc); + + 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 ())); - /* - 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; + return pitches; } -void -Chord::rebuild_from_base (Array* pitch_arr_p, int base_i) + +/* --Het lijkt me dat dit in het paarse gedeelte moet. */ +Simultaneous_music * +Chord::get_chord (SCM tonic, SCM add, SCM sub, SCM inversion, SCM bass, SCM dur) { - assert (base_i >= 0); - Musical_pitch last (0, 0, -5); - Array new_arr; - for (int i = 0; i < pitch_arr_p->size (); i++) + SCM pitches = tonic_add_sub_to_pitches (tonic, add, sub); + SCM list = SCM_EOL; + if (inversion != SCM_EOL) { - Musical_pitch p = (*pitch_arr_p)[(base_i + i) % pitch_arr_p->size ()]; - if (p < last) + /* If inversion requested, check first if the note is part of chord */ + SCM s = member_pitch (inversion, pitches); + if (s != SCM_BOOL_F) { - p.octave_i_ = last.octave_i_; - if (p < last) - p.octave_i_++; + /* Then, delete and add as base note, ie: the inversion */ + pitches = scm_delete (s, pitches); + Note_req* n = new Note_req; + n->set_mus_property ("pitch", gh_car (add_below_tonic (s, pitches))); + n->set_mus_property ("duration", dur); + n->set_mus_property ("inversion", SCM_BOOL_T); + list = gh_cons (n->self_scm (), list); + scm_unprotect_object (n->self_scm ()); } - new_arr.push (p); - last = p; + else + warning (_f ("invalid inversion pitch: not part of chord: %s", + unsmob_pitch (inversion)->str ())); } - *pitch_arr_p = new_arr; -} -void -Chord::rebuild_insert_inversion (Array* pitch_arr_p, int tonic_i) -{ - 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 ()) + /* Bass is easy, just add if requested */ + if (bass != SCM_EOL) { - inversion.octave_i_ = (*pitch_arr_p)[0].octave_i_ - 1; - while (inversion < (*pitch_arr_p)[0]) - inversion.octave_i_++; + Note_req* n = new Note_req; + n->set_mus_property ("pitch", gh_car (add_below_tonic (bass, pitches))); + n->set_mus_property ("duration", dur); + n->set_mus_property ("bass", SCM_BOOL_T); + list = gh_cons (n->self_scm (), list); + scm_unprotect_object (n->self_scm ()); + } + + for (SCM i = pitches; gh_pair_p (i); i = gh_cdr (i)) + { + Note_req* n = new Note_req; + n->set_mus_property ("pitch", gh_car (i)); + n->set_mus_property ("duration", dur); + list = gh_cons (n->self_scm (), list); + scm_unprotect_object (n->self_scm ()); } - for (int i = 0; i < pitch_arr_p->size (); i++) - if ((*pitch_arr_p)[i] > inversion) - { - pitch_arr_p->insert (inversion, i); - break; - } -} -void -Chord::rebuild_with_bass (Array* pitch_arr_p, int bass_i) -{ - assert (bass_i >= 0); - Musical_pitch bass = pitch_arr_p->get (bass_i); - // 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); + Simultaneous_music*v = new Request_chord (SCM_EOL); + v->set_mus_property ("elements", list); + + return v; } +