+pl 15.jcn1
+ - chord inversion:
+ * enter C/E
+ * display chord names according to boolean property
+ \property Score.chordInversion;
+
pl 15
pl 14.hwn1
.. ?
* chords
- - jazz style inversions C/E => <e g c>
- guitar chords (fret diagrams)
- other chord name styles (american(?) style)
- basso continuo
MAJOR_VERSION=1
MINOR_VERSION=1
PATCH_LEVEL=15
-MY_PATCH_LEVEL=
+MY_PATCH_LEVEL=jcn1
# use the above to send patches: MY_PATCH_LEVEL is always empty for a
# released version.
timeSignatureStyle oldn/m Set symbol explicitly,
n/m=2/2,3/2,3/4,4/4,6/4 or 9/4.
-
[Staff?]
instrument ascii midi instrument table lookup
+[Score]
+chordInversion 0/1 Find and display chord with inversion?
+
1) after beam slope damping table suggested in [Wanske]
2) [Wanske] as well as [Ross] suggests that beams sloped upward must not
--- /dev/null
+\header{
+enteredby = "jcn";
+copyright = "public domain";
+TestedFeatures = "chord inversions";
+}
+
+inversions = \notes\transpose c''\chords{
+ c1 c-sus c-6 c/e c/g c/d
+ % now try to find chords with inversions
+ \property Score.chordInversion = 1
+ c1 c-sus c-6 c/e c/g c/d
+}
+
+\score{
+ <
+ \type ChordNames \inversions
+ \type Staff \inversions
+ >
+}
\header{
enteredby = "jcn";
-copyright = "PD";
+copyright = "public domain";
TestedFeatures = "This file tests Feta embedded slurs" +
"(Feta definitively is not an abbreviation of Font-En-TjA)";
}
TODO:
- move this stuff to new Item class Chord_name
- switch on property, add american (?) chordNameStyle
- - jazz inversions
Scalar chordNameStyle = get_property ("chordNameStyle");
if (chordNameStyle == "Banter")
if (alignment.isnum_b())
text_p->align_dir_= (Direction)(int)alignment;
+
+ /*
+ find tonic: after longest line of triads
+ */
+
+ int tonic_i = 0;
+ Scalar chord_inversions = get_property ("chordInversion");
+ if (chord_inversions.to_bool ())
+ {
+ int longest_i = 0;
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ for (int j = 0; j < pitch_arr_.size (); j++)
+ {
+ int gap = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_
+ - pitch_arr_[(i + j) % pitch_arr_.size ()].notename_i_;
+ while (gap < 0)
+ gap += 7;
+ gap %= 7;
+ if (gap != 2)
+ {
+ if (j > longest_i)
+ {
+ longest_i = j;
+ tonic_i = i;
+ }
+ break;
+ }
+ }
+
+ int biggest_i = 0;
+ if (!longest_i)
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ {
+ int gap = pitch_arr_[i].notename_i_
+ - pitch_arr_[(i - 1 + pitch_arr_.size ())
+ % pitch_arr_.size ()].notename_i_;
+ while (gap < 0)
+ gap += 7;
+ gap %= 7;
+ if (gap > biggest_i)
+ {
+ biggest_i = gap;
+ tonic_i = i;
+ }
+ }
+ }
+
+ Musical_pitch inversion = pitch_arr_[0];
+ if (tonic_i)
+ {
+ Musical_pitch last (0, 0, -5);
+ Array<Musical_pitch> pitches;
+ for (int i = 0; i < pitch_arr_.size (); i++)
+ {
+ Musical_pitch p = pitch_arr_[(tonic_i + i) % pitch_arr_.size ()];
+ if (p < last)
+ {
+ p.octave_i_ = last.octave_i_;
+ if (p < last)
+ p.octave_i_++;
+ }
+ pitches.push (p);
+ last = p;
+ }
+ pitch_arr_ = pitches;
+ }
+
Musical_pitch tonic = pitch_arr_[0];
Array<Musical_pitch> scale;
// 7 always means 7-...
scale.push (Musical_pitch (6, -1)); // b
+
for (int i = 0; i < scale.size (); i++)
scale[i].transpose (tonic);
}
}
- text_p->text_str_ = tonic_str + "$^{" + add_str + "}$";
+ String inversion_str;
+ if (tonic_i)
+ {
+ inversion_str = inversion.str ();
+ inversion_str = "/" + inversion_str.left_str (1).upper_str ()
+ + acc[tonic.accidental_i_ + 2];
+
+ }
+ text_p->text_str_ = tonic_str + "$^{" + add_str + "}$" + inversion_str;
Text_item* item_p = new Text_item (text_p);
item_p->dir_ = DOWN;
item_p->fat_b_ = true;
void add_requests (Simultaneous_music*v);
Simultaneous_music * get_note_element (Note_req * ,Duration *);
- Simultaneous_music * get_chord (Musical_pitch, Array<Musical_pitch>*, Array<Musical_pitch>*, Duration);
+ Simultaneous_music * get_chord (Musical_pitch, Array<Musical_pitch>*, Array<Musical_pitch>*, Musical_pitch*, Duration);
Simultaneous_music* get_rest_element (String, Duration *);
Simultaneous_music* get_word_element (String, Duration*);
Melodic_req* get_melodic_req (Melodic_req* melodic, int quotes);
}
Simultaneous_music *
-My_lily_parser::get_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Duration d)
+My_lily_parser::get_chord (Musical_pitch tonic, Array<Musical_pitch>* add_arr_p, Array<Musical_pitch>* sub_arr_p, Musical_pitch* inversion_p, Duration d)
{
Simultaneous_music*v = new Request_chord;
v->set_spot (here_input ());
- Note_req* n = new Note_req;
- n->pitch_ = tonic;
- n->duration_ = d;
- v->add_music (n);
-
for (int i = 0; i < add_arr_p->size (); i++)
{
Musical_pitch p = tonic;
i++;
}
+ /*
+ add tonic
+ */
+ if (!add_arr_p->size () || ((*add_arr_p)[0] != tonic))
+ add_arr_p->insert (tonic, 0);
+
+ Array<Musical_pitch> 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];
- Note_req* n = new Note_req;
- n->pitch_ = p;
- n->duration_ = d;
- for (int j = 0; j < sub_arr_p->size (); j++)
+ int j = 0;
+ for (; j < sub_arr_p->size (); j++)
+ if (p == (*sub_arr_p)[j])
+ break;
+ if (j == sub_arr_p->size ())
+ pitch_arr.push (p);
+ }
+
+ if (inversion_p)
+ {
+ int i = 0;
+ for (; i < pitch_arr.size (); i++)
+ if ((pitch_arr[i].notename_i_ == inversion_p->notename_i_)
+ && (pitch_arr[i].accidental_i_ == inversion_p->accidental_i_))
+ break;
+ if (i == pitch_arr.size ())
+ warning (_ ("invalid inversion pitch (not part of chord)"));
+ else
{
- if (p == (*sub_arr_p)[j])
+ Array<Musical_pitch> pitches;
+ Musical_pitch last (0, 0, -5);
+ for (int j = 0; j < pitch_arr.size (); j++)
{
- delete n;
- n = 0;
- break;
+ Musical_pitch p = pitch_arr[(j + i) % pitch_arr.size ()];
+ if (p < last)
+ {
+ p.octave_i_ = last.octave_i_;
+ if (p < last)
+ p.octave_i_++;
+ }
+ pitches.push (p);
+ last = p;
}
+ pitch_arr = pitches;
}
- if (n)
- v->add_music (n);
+ delete inversion_p;
+ }
+
+ for (int i = 0; i < pitch_arr.size (); i++)
+ {
+ Musical_pitch p = pitch_arr[i];
+ Note_req* n = new Note_req;
+ n->pitch_ = p;
+ n->duration_ = d;
+ v->add_music (n);
}
v->set_spot (here_input ());
%type <pitch_arr> pitch_list
%type <music> chord notemode_chord
%type <pitch_arr> chord_additions chord_subtractions
-%type <pitch> chord_addsub chord_note
+%type <pitch> chord_addsub chord_note chord_inversion notemode_chord_inversion
%type <midi> midi_block midi_body
%type <duration> duration_length
;
chord:
- steno_tonic_pitch notemode_duration chord_additions chord_subtractions {
- $$ = THIS->get_chord (*$1, $3, $4, *$2);
+ steno_tonic_pitch notemode_duration chord_additions chord_subtractions chord_inversion {
+ $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
};
notemode_chord:
- steno_musical_pitch notemode_duration chord_additions chord_subtractions {
- $$ = THIS->get_chord (*$1, $3, $4, *$2);
+ steno_musical_pitch notemode_duration chord_additions chord_subtractions notemode_chord_inversion {
+ $$ = THIS->get_chord (*$1, $3, $4, $5, *$2);
};
chord_additions:
| CHORDMODIFIER_PITCH optional_dot
;
+chord_inversion:
+ {
+ $$ = 0;
+ }
+ | '/' steno_tonic_pitch {
+ $$ = $2
+ }
+ ;
+
+notemode_chord_inversion:
+ {
+ $$ = 0;
+ }
+ | '/' steno_musical_pitch {
+ $$ = $2
+ }
+ ;
+
chord_note:
UNSIGNED {
$$ = new Musical_pitch;