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 "paper-def.hh"
13 #include "paper-def.hh"
15 #include "dimensions.hh"
16 #include "g-text-item.hh"
18 ADD_THIS_TRANSLATOR (Chord_name_engraver);
20 Chord_name_engraver::Chord_name_engraver ()
25 Chord_name_engraver::acknowledge_element (Score_element_info i)
27 if (Note_req* n = dynamic_cast<Note_req*> (i.req_l_))
28 pitch_arr_.push (n->pitch_);
32 Chord_name_engraver::do_try_music (Music* m)
34 if (Note_req* n = dynamic_cast<Note_req*> (m))
36 pitch_arr_.push (n->pitch_);
43 find tonic: after longest line of triads
46 Chord_name_engraver::find_tonic_i () const
50 for (int i = 0; i < pitch_arr_.size (); i++)
51 for (int j = 0; j < pitch_arr_.size (); j++)
53 int gap = pitch_arr_[(i + j + 1) % pitch_arr_.size ()].notename_i_
54 - pitch_arr_[(i + j) % pitch_arr_.size ()].notename_i_;
71 for (int i = 0; i < pitch_arr_.size (); i++)
73 int gap = pitch_arr_[i].notename_i_
74 - pitch_arr_[(i - 1 + pitch_arr_.size ())
75 % pitch_arr_.size ()].notename_i_;
89 Chord_name_engraver::rebuild_pitch_arr (int tonic_i) const
91 Musical_pitch last (0, 0, -5);
92 Array<Musical_pitch> pitches;
93 for (int i = 0; i < pitch_arr_.size (); i++)
95 Musical_pitch p = pitch_arr_[(tonic_i + i) % pitch_arr_.size ()];
98 p.octave_i_ = last.octave_i_;
109 Chord_name_engraver::do_process_requests ()
111 if (text_p_arr_.size ())
113 if (!pitch_arr_.size ())
117 Banter style chord names (almost).
119 - move this stuff to new Item class Chord_name
120 - switch on property, add american (?) chordNameStyle
122 Scalar chordNameStyle = get_property ("chordNameStyle", 0);
123 if (chordNameStyle == "Banter")
124 chord = pitches_to_banter (pitch_arr_));
129 Musical_pitch inversion = pitch_arr_[0];
130 Scalar chord_inversions = get_property ("chordInversion", 0);
131 if (chord_inversions.to_bool ())
133 tonic_i = find_tonic_i ();
135 pitch_arr_ = rebuild_pitch_arr (tonic_i);
139 G_text_item* item_p = new G_text_item;
141 item_p->text_str_ = banter_str (pitch_arr_, tonic_i, inversion);
143 Scalar style = get_property ("textstyle", 0);
144 if (style.length_i ())
145 item_p->style_str_ = style;
147 text_p_arr_.push (item_p);
148 announce_element (Score_element_info (item_p, 0));
152 Chord_name_engraver::do_pre_move_processing ()
154 for (int i=0; i < text_p_arr_.size (); i++)
156 typeset_element (text_p_arr_[i]);
158 text_p_arr_.clear ();
163 Chord_name_engraver::banter_str (Array<Musical_pitch> pitch_arr, int tonic_i, Musical_pitch inversion) const
165 Musical_pitch tonic = pitch_arr[0];
167 Array<Musical_pitch> scale;
168 scale.push (Musical_pitch (0)); // c
169 scale.push (Musical_pitch (1)); // d
170 scale.push (Musical_pitch (2)); // e
171 scale.push (Musical_pitch (3)); // f
172 scale.push (Musical_pitch (4)); // g
173 scale.push (Musical_pitch (5)); // a
174 // 7 always means 7-...
175 scale.push (Musical_pitch (6, -1)); // b
178 for (int i = 0; i < scale.size (); i++)
179 scale[i].transpose (tonic);
181 //urg, should do translation in scheme.
182 char const *acc[] = {"\\textflat\\textflat ", "\\textflat ", "", "\\textsharp " , "\\textsharp\\textsharp "};
183 String tonic_str = tonic.str ();
184 tonic_str = tonic_str.left_str (1).upper_str ()
185 + acc[tonic.accidental_i_ + 2];
191 for (int i=1; i < pitch_arr.size (); i++)
193 Musical_pitch p = pitch_arr[i];
194 int trap = p.notename_i_ - tonic.notename_i_
195 + (p.octave_i_ - tonic.octave_i_) * 7 + 1;
196 while (trap - last_trap > 2)
199 sub_str += sep_str + "no" + to_str (last_trap);
203 int accidental = p.accidental_i_ - scale[(trap - 1) % 7].accidental_i_;
204 if ((trap == 3) && (accidental == -1))
205 tonic_str += "m"; // hmm
206 else if (accidental || (!(trap % 2) || ((i + 1 == pitch_arr.size ()) && (trap > 5))))
209 if ((trap == 7) && (accidental == 1))
213 add_str += to_str (trap);
215 add_str += accidental < 0 ? "-" : "+";
221 String inversion_str;
224 inversion_str = inversion.str ();
225 inversion_str = "/" + inversion_str.left_str (1).upper_str ()
226 + acc[tonic.accidental_i_ + 2];
230 String str = tonic_str + "$^{" + add_str + sub_str + "}$" + inversion_str;