2 tie-performer.cc -- implement Tie_performer
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2003 Jan Nieuwenhuizen <janneke@gnu.org>
11 #include "audio-item.hh"
14 #include "performer.hh"
16 struct CNote_melodic_tuple
{
20 CNote_melodic_tuple ();
21 CNote_melodic_tuple (Audio_note
*, Music
*, Moment
);
22 static int pitch_compare (CNote_melodic_tuple
const &, CNote_melodic_tuple
const &);
23 static int time_compare (CNote_melodic_tuple
const &, CNote_melodic_tuple
const &);
26 inline int compare (CNote_melodic_tuple
const &a
, CNote_melodic_tuple
const &b
)
28 return CNote_melodic_tuple::time_compare (a
,b
);
33 Manufacture ties. Acknowledge notes, and put them into a
34 priority queue. If we have a Music, connect the notes that finish
35 just at this time, and note that start at this time.
37 TODO: should share code with Tie_engraver ?
39 class Tie_performer
: public Performer
42 TRANSLATOR_DECLARATIONS(Tie_performer
);
46 Array
<CNote_melodic_tuple
> now_notes_
;
47 Array
<CNote_melodic_tuple
> tied_notes_
;
52 Link_array
<Audio_tie
> ties_
;
55 virtual void initialize ();
56 virtual void start_translation_timestep ();
57 virtual void stop_translation_timestep ();
58 virtual void acknowledge_audio_element (Audio_element_info
);
59 virtual bool try_music (Music
*);
60 virtual void create_audio_elements ();
64 Tie_performer::Tie_performer ()
67 ties_created_
= false;
70 ENTER_DESCRIPTION (Tie_performer
, "", "",
76 Tie_performer::initialize ()
83 Tie_performer::try_music (Music
*m
)
94 Tie_performer::acknowledge_audio_element (Audio_element_info i
)
96 if (Audio_note
*nh
= dynamic_cast<Audio_note
*> (i
.elem_
))
99 if (m
->is_mus_type ("note-event"))
100 now_notes_
.push (CNote_melodic_tuple (nh
, m
, now_mom ()+ m
->get_length ()));
105 Tie_performer::create_audio_elements ()
108 This is a nested loop. Not optimal, but good enough.
110 if (tied_notes_
.size ())
112 Moment now
= now_mom();
113 for (int i
= tied_notes_
.size (); i
--; )
115 if (tied_notes_
[i
].end_
!= now
)
118 for (int j
= now_notes_
.size(); j
--;)
121 = Pitch::compare (*unsmob_pitch (tied_notes_
[i
].event_
->get_mus_property ("pitch")),
122 *unsmob_pitch (now_notes_
[j
].event_
->get_mus_property ("pitch")));
127 Audio_tie
* p
= new Audio_tie
;
128 p
->set_note (LEFT
, tied_notes_
[i
].note_
);
129 p
->set_note (RIGHT
, now_notes_
[j
].note_
);
131 announce_element (Audio_element_info (p
, event_
));
132 ties_created_
= true;
144 Tie_performer::stop_translation_timestep ()
146 if (prev_event_
&& tied_notes_
.size () && !ties_
.size ()
147 && now_notes_
.size ())
149 prev_event_
->origin ()->warning (_ ("No ties were performed."));
160 tied_notes_
= now_notes_
;
161 prev_event_
= event_
;
165 now_notes_
.clear ();
167 for (int i
=ties_
.size (); i
--;)
169 ties_
[i
]->note_drul_
[RIGHT
]->tie_to (ties_
[i
]->note_drul_
[LEFT
]);
176 Tie_performer::start_translation_timestep ()
179 ties_created_
= false;
180 Moment now
= now_mom ();
181 for (int i
= tied_notes_
.size (); i
-- ;)
183 if (tied_notes_
[i
].end_
< now
)
191 CNote_melodic_tuple::CNote_melodic_tuple ()
198 CNote_melodic_tuple::CNote_melodic_tuple (Audio_note
*h
, Music
*m
, Moment mom
)
206 CNote_melodic_tuple::pitch_compare (CNote_melodic_tuple
const&h1
,
207 CNote_melodic_tuple
const &h2
)
209 SCM p1
= h1
.event_
->get_mus_property ("pitch");
210 SCM p2
= h2
.event_
->get_mus_property ("pitch");
211 return Pitch::compare (*unsmob_pitch (p1
),
216 CNote_melodic_tuple::time_compare (CNote_melodic_tuple
const&h1
,
217 CNote_melodic_tuple
const &h2
)
219 return (h1
.end_
- h2
.end_
).main_part_
.sign ();