2 chord-name-engraver.cc -- implement Chord_name_engraver
4 source file of the GNU LilyPond music typesetter
6 (c) 1998 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "chord-name-engraver.hh"
10 #include "musical-request.hh"
11 #include "text-item.hh"
12 #include "paper-def.hh"
14 #include "paper-def.hh"
16 #include "dimensions.hh"
17 #include "g-text-item.hh"
19 ADD_THIS_TRANSLATOR (Chord_name_engraver);
21 Chord_name_engraver::Chord_name_engraver ()
26 Chord_name_engraver::acknowledge_element (Score_element_info i)
28 if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
29 pitch_arr_.push (n->pitch_);
33 Chord_name_engraver::do_try_music (Music* m)
35 if (Note_req* n = dynamic_cast<Note_req*> (m))
37 pitch_arr_.push (n->pitch_);
46 Split this routine into neat packets
49 Chord_name_engraver::do_process_requests ()
51 if (text_p_arr_.size ())
53 if (!pitch_arr_.size ())
57 Banter style chord names (almost).
59 - move this stuff to new Item class Chord_name
60 - switch on property, add american (?) chordNameStyle
62 Scalar chordNameStyle = get_property ("chordNameStyle", 0);
63 if (chordNameStyle == "Banter")
64 chord = pitches_to_banter (pitch_arr_));
70 find tonic: after longest line of triads
74 Scalar chord_inversions = get_property ("chordInversion", 0);
75 if (chord_inversions.to_bool ())
78 for (int i = 0; i < pitch_arr_.size (); i++)
79 for (int j = 0; j < pitch_arr_.size (); j++)
81 int gap = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_
82 - pitch_arr_[(i + j) % pitch_arr_.size ()].notename_i_;
99 for (int i = 0; i < pitch_arr_.size (); i++)
101 int gap = pitch_arr_[i].notename_i_
102 - pitch_arr_[(i - 1 + pitch_arr_.size ())
103 % pitch_arr_.size ()].notename_i_;
115 Musical_pitch inversion = pitch_arr_[0];
118 Musical_pitch last (0, 0, -5);
119 Array<Musical_pitch> pitches;
120 for (int i = 0; i < pitch_arr_.size (); i++)
122 Musical_pitch p = pitch_arr_[(tonic_i + i) % pitch_arr_.size ()];
125 p.octave_i_ = last.octave_i_;
132 pitch_arr_ = pitches;
135 Musical_pitch tonic = pitch_arr_[0];
137 Array<Musical_pitch> scale;
138 scale.push (Musical_pitch (0)); // c
139 scale.push (Musical_pitch (1)); // d
140 scale.push (Musical_pitch (2)); // e
141 scale.push (Musical_pitch (3)); // f
142 scale.push (Musical_pitch (4)); // g
143 scale.push (Musical_pitch (5)); // a
144 // 7 always means 7-...
145 scale.push (Musical_pitch (6, -1)); // b
148 for (int i = 0; i < scale.size (); i++)
149 scale[i].transpose (tonic);
151 //urg, should do translation in scheme.
152 char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "};
153 String tonic_str = tonic.str ();
154 tonic_str = tonic_str.left_str (1).upper_str ()
155 + acc[tonic.accidental_i_ + 2];
159 for (int i=1; i < pitch_arr_.size (); i++)
161 Musical_pitch p = pitch_arr_[i];
162 int trap = p.notename_i_ - tonic.notename_i_
163 + (p.octave_i_ - tonic.octave_i_) * 7 + 1;
164 int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_;
165 if ((trap == 3) && (accidental == -1))
166 tonic_str += "m"; // hmm
167 else if (accidental || (!(trap % 2) || ((i + 1 == pitch_arr_.size ()) && (trap > 5))))
170 if ((trap == 7) && (accidental == 1))
174 add_str += to_str (trap);
176 add_str += accidental < 0 ? "-" : "+";
182 String inversion_str;
185 inversion_str = inversion.str ();
186 inversion_str = "/" + inversion_str.left_str (1).upper_str ()
187 + acc[tonic.accidental_i_ + 2];
191 G_text_item* item_p = new G_text_item;
194 item_p->text_str_ = tonic_str + "$^{" + add_str + "}$" + inversion_str;
195 Scalar style = get_property ("textstyle", 0);
196 if (style.length_i ())
197 item_p->style_str_ = style;
199 text_p_arr_.push (item_p);
200 announce_element (Score_element_info (item_p, 0));
204 Chord_name_engraver::do_pre_move_processing ()
206 for (int i=0; i < text_p_arr_.size (); i++)
208 typeset_element (text_p_arr_[i]);
210 text_p_arr_.clear ();