LEFT | RIGHT |
1 /* | 1 /* |
2 This file is part of LilyPond, the GNU music typesetter. | 2 This file is part of LilyPond, the GNU music typesetter. |
3 | 3 |
4 Copyright (C) 1998--2011 Jan Nieuwenhuizen <janneke@gnu.org> | 4 Copyright (C) 1998--2011 Jan Nieuwenhuizen <janneke@gnu.org> |
5 | 5 |
6 LilyPond is free software: you can redistribute it and/or modify | 6 LilyPond is free software: you can redistribute it and/or modify |
7 it under the terms of the GNU General Public License as published by | 7 it under the terms of the GNU General Public License as published by |
8 the Free Software Foundation, either version 3 of the License, or | 8 the Free Software Foundation, either version 3 of the License, or |
9 (at your option) any later version. | 9 (at your option) any later version. |
10 | 10 |
(...skipping 26 matching lines...) Expand all Loading... |
37 TRANSLATOR_DECLARATIONS (Chord_name_engraver); | 37 TRANSLATOR_DECLARATIONS (Chord_name_engraver); |
38 protected: | 38 protected: |
39 void stop_translation_timestep (); | 39 void stop_translation_timestep (); |
40 void process_music (); | 40 void process_music (); |
41 virtual void finalize (); | 41 virtual void finalize (); |
42 virtual void derived_mark () const; | 42 virtual void derived_mark () const; |
43 DECLARE_TRANSLATOR_LISTENER (note); | 43 DECLARE_TRANSLATOR_LISTENER (note); |
44 DECLARE_TRANSLATOR_LISTENER (rest); | 44 DECLARE_TRANSLATOR_LISTENER (rest); |
45 private: | 45 private: |
46 Item *chord_name_; | 46 Item *chord_name_; |
47 vector<Stream_event*> notes_; | 47 vector<Stream_event *> notes_; |
48 | 48 |
49 SCM last_chord_; | 49 SCM last_chord_; |
50 Stream_event *rest_event_; | 50 Stream_event *rest_event_; |
51 }; | 51 }; |
52 | 52 |
53 void | 53 void |
54 Chord_name_engraver::finalize () | 54 Chord_name_engraver::finalize () |
55 { | 55 { |
56 } | 56 } |
57 | 57 |
58 void | 58 void |
59 Chord_name_engraver::derived_mark () const | 59 Chord_name_engraver::derived_mark () const |
60 { | 60 { |
61 scm_gc_mark (last_chord_); | 61 scm_gc_mark (last_chord_); |
62 } | 62 } |
63 | 63 |
64 Chord_name_engraver::Chord_name_engraver () | 64 Chord_name_engraver::Chord_name_engraver () |
65 { | 65 { |
66 chord_name_ = 0; | 66 chord_name_ = 0; |
67 last_chord_ = SCM_EOL; | 67 last_chord_ = SCM_EOL; |
68 rest_event_ = 0; | 68 rest_event_ = 0; |
69 } | 69 } |
70 | 70 |
71 void | 71 void |
72 Chord_name_engraver::process_music () | 72 Chord_name_engraver::process_music () |
73 { | 73 { |
74 SCM markup; | 74 SCM markup; |
75 SCM bass = SCM_EOL; | 75 SCM bass = SCM_EOL; |
76 SCM inversion = SCM_EOL; | 76 SCM inversion = SCM_EOL; |
77 SCM pitches = SCM_EOL; | 77 SCM pitches = SCM_EOL; |
78 | 78 |
79 if (rest_event_) | 79 if (rest_event_) |
80 { | 80 { |
81 SCM no_chord_markup = get_property ("noChordSymbol"); | 81 SCM no_chord_markup = get_property ("noChordSymbol"); |
82 if (!Text_interface::is_markup (no_chord_markup)) | 82 if (!Text_interface::is_markup (no_chord_markup)) |
83 return; | 83 return; |
84 markup = no_chord_markup; | 84 markup = no_chord_markup; |
85 } | 85 } |
86 else | 86 else |
87 { | 87 { |
88 if (!notes_.size ()) | 88 if (!notes_.size ()) |
89 return; | 89 return; |
90 | 90 |
91 Stream_event *inversion_event = 0; | 91 Stream_event *inversion_event = 0; |
92 for (vsize i = 0; i < notes_.size (); i++) | 92 for (vsize i = 0; i < notes_.size (); i++) |
93 { | 93 { |
94 Stream_event *n = notes_[i]; | 94 Stream_event *n = notes_[i]; |
95 SCM p = n->get_property ("pitch"); | 95 SCM p = n->get_property ("pitch"); |
96 if (!unsmob_pitch (p)) | 96 if (!unsmob_pitch (p)) |
97 continue; | 97 continue; |
98 | 98 |
99 if (n->get_property ("inversion") == SCM_BOOL_T) | 99 if (n->get_property ("inversion") == SCM_BOOL_T) |
100 { | 100 { |
101 inversion_event = n; | 101 inversion_event = n; |
102 inversion = p; | 102 inversion = p; |
| 103 } |
| 104 else if (n->get_property ("bass") == SCM_BOOL_T) |
| 105 bass = p; |
| 106 else |
| 107 pitches = scm_cons (p, pitches); |
103 } | 108 } |
104 else if (n->get_property ("bass") == SCM_BOOL_T) | |
105 bass = p; | |
106 else | |
107 pitches = scm_cons (p, pitches); | |
108 } | |
109 | 109 |
110 if (inversion_event) | 110 if (inversion_event) |
111 { | |
112 SCM oct = inversion_event->get_property ("octavation"); | |
113 if (scm_is_number (oct)) | |
114 { | 111 { |
115 Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch")); | 112 SCM oct = inversion_event->get_property ("octavation"); |
116 int octavation = scm_to_int (oct); | 113 if (scm_is_number (oct)) |
117 Pitch orig = p->transposed (Pitch (-octavation, 0, 0)); | 114 { |
| 115 Pitch *p = unsmob_pitch (inversion_event->get_property ("pitch")); |
| 116 int octavation = scm_to_int (oct); |
| 117 Pitch orig = p->transposed (Pitch (-octavation, 0, 0)); |
118 | 118 |
119 pitches = scm_cons (orig.smobbed_copy (), pitches); | 119 pitches = scm_cons (orig.smobbed_copy (), pitches); |
| 120 } |
| 121 else |
| 122 programming_error ("inversion does not have original pitch"); |
120 } | 123 } |
121 else | |
122 programming_error ("inversion does not have original pitch"); | |
123 } | |
124 | 124 |
125 pitches = scm_sort_list (pitches, Pitch::less_p_proc); | 125 pitches = scm_sort_list (pitches, Pitch::less_p_proc); |
126 | 126 |
127 SCM capo_proc = ly_lily_module_constant ("capo-handler"); | 127 SCM capo_proc = ly_lily_module_constant ("capo-handler"); |
128 markup = scm_call_4 (capo_proc, pitches, bass, inversion, | 128 markup = scm_call_4 (capo_proc, pitches, bass, inversion, |
129 context ()->self_scm ()); | 129 context ()->self_scm ()); |
130 } | 130 } |
131 /* | 131 /* |
132 Ugh. | 132 Ugh. |
133 */ | 133 */ |
134 SCM chord_as_scm = scm_cons (pitches, scm_cons (bass, inversion)); | 134 SCM chord_as_scm = scm_cons (pitches, scm_cons (bass, inversion)); |
135 | 135 |
136 chord_name_ = make_item ("ChordName",· | 136 chord_name_ = make_item ("ChordName", |
137 rest_event_ ? rest_event_->self_scm () : notes_[0]->self_scm ()); | 137 rest_event_ ? rest_event_->self_scm () : notes_[0]->s
elf_scm ()); |
138 chord_name_->set_property ("text", markup); | 138 chord_name_->set_property ("text", markup); |
139 | 139 |
140 SCM chord_changes = get_property("chordChanges"); | 140 SCM chord_changes = get_property ("chordChanges"); |
141 if (to_boolean (chord_changes) && scm_is_pair (last_chord_) | 141 if (to_boolean (chord_changes) && scm_is_pair (last_chord_) |
142 && ly_is_equal (chord_as_scm, last_chord_)) | 142 && ly_is_equal (chord_as_scm, last_chord_)) |
143 chord_name_->set_property ("begin-of-line-visible", SCM_BOOL_T); | 143 chord_name_->set_property ("begin-of-line-visible", SCM_BOOL_T); |
144 | 144 |
145 last_chord_ = chord_as_scm; | 145 last_chord_ = chord_as_scm; |
146 } | 146 } |
147 | 147 |
148 IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note); | 148 IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, note); |
149 void | 149 void |
150 Chord_name_engraver::listen_note (Stream_event *ev) | 150 Chord_name_engraver::listen_note (Stream_event *ev) |
151 { | 151 { |
152 notes_.push_back (ev); | 152 notes_.push_back (ev); |
153 } | 153 } |
154 | 154 |
155 IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, rest); | 155 IMPLEMENT_TRANSLATOR_LISTENER (Chord_name_engraver, rest); |
156 void | 156 void |
157 Chord_name_engraver::listen_rest (Stream_event *ev) | 157 Chord_name_engraver::listen_rest (Stream_event *ev) |
158 { | 158 { |
159 ASSIGN_EVENT_ONCE(rest_event_, ev); | 159 ASSIGN_EVENT_ONCE (rest_event_, ev); |
160 } | 160 } |
161 | 161 |
162 void | 162 void |
163 Chord_name_engraver::stop_translation_timestep () | 163 Chord_name_engraver::stop_translation_timestep () |
164 { | 164 { |
165 chord_name_ = 0; | 165 chord_name_ = 0; |
166 notes_.clear (); | 166 notes_.clear (); |
167 rest_event_ = 0; | 167 rest_event_ = 0; |
168 } | 168 } |
169 | 169 |
170 /* | 170 /* |
171 The READs description is not strictly accurate: | 171 The READs description is not strictly accurate: |
172 which properties are read depend on the chord naming function active. | 172 which properties are read depend on the chord naming function active. |
173 */ | 173 */ |
174 ADD_TRANSLATOR (Chord_name_engraver, | 174 ADD_TRANSLATOR (Chord_name_engraver, |
175 » » /* doc */ | 175 /* doc */ |
176 » » "Catch note and rest events and generate the appropriate chordna
me.", | 176 "Catch note and rest events and generate the appropriate chordna
me.", |
177 | 177 |
178 » » /* create */ | 178 /* create */ |
179 » » "ChordName ", | 179 "ChordName ", |
180 | 180 |
181 » » /* read */ | 181 /* read */ |
182 » » "chordChanges " | 182 "chordChanges " |
183 » » "chordNameExceptions " | 183 "chordNameExceptions " |
184 » » "chordNameFunction " | 184 "chordNameFunction " |
185 » » "chordNoteNamer " | 185 "chordNoteNamer " |
186 » » "chordRootNamer " | 186 "chordRootNamer " |
187 » » "chordNameExceptions " | 187 "chordNameExceptions " |
188 » » "majorSevenSymbol " | 188 "majorSevenSymbol " |
189 "noChordSymbol ", | 189 "noChordSymbol ", |
190 | 190 |
191 » » /* write */ | 191 /* write */ |
192 » » "" | 192 "" |
193 » » ); | 193 ); |
LEFT | RIGHT |