2 tie-performer.cc -- implement Tie_performer
4 source file of the GNU LilyPond music typesetter
6 (c) 1999--2001 Jan Nieuwenhuizen <janneke@gnu.org>
10 #include "command-request.hh"
11 #include "audio-item.hh"
12 #include "musical-request.hh"
14 #include "performer.hh"
16 struct CNote_melodic_tuple
{
20 CNote_melodic_tuple ();
21 CNote_melodic_tuple (Audio_note
*, Melodic_req
*, 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 Tie_req, 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 VIRTUAL_COPY_CONS (Translator
);
46 PQueue
<CNote_melodic_tuple
> past_notes_pq_
;
48 Array
<CNote_melodic_tuple
> now_notes_
;
49 Array
<CNote_melodic_tuple
> stopped_notes_
;
50 Link_array
<Audio_tie
> tie_p_arr_
;
53 virtual void initialize ();
54 virtual void start_translation_timestep ();
55 virtual void stop_translation_timestep ();
56 virtual void acknowledge_audio_element (Audio_element_info
);
57 virtual bool try_music (Music
*);
58 virtual void create_audio_elements ();
62 Tie_performer::Tie_performer ()
68 ADD_THIS_TRANSLATOR (Tie_performer
);
72 Tie_performer::Tie_performer ()
75 // if we don't do this, lily dumps core
76 // which means that ``initialize'' and
77 // ``start_translation_timestep'' did not happen?!
83 Tie_performer::initialize ()
90 Tie_performer::try_music (Music
*m
)
94 if (Tie_req
* c
= dynamic_cast<Tie_req
*> (m
))
104 Tie_performer::acknowledge_audio_element (Audio_element_info i
)
106 if (Audio_note
*nh
= dynamic_cast<Audio_note
*> (i
.elem_l_
))
108 Note_req
* m
= dynamic_cast<Note_req
* > (i
.req_l_
);
111 now_notes_
.push (CNote_melodic_tuple (nh
, m
, now_mom ()+ m
->length_mom ()));
116 Tie_performer::create_audio_elements ()
118 if (req_l_
&& ! done_
)
120 Moment now
= now_mom ();
121 Link_array
<Audio_note
> nharr
;
123 stopped_notes_
.clear ();
124 while (past_notes_pq_
.size ()
125 && past_notes_pq_
.front ().end_
== now
)
126 stopped_notes_
.push (past_notes_pq_
.get ());
133 now_notes_
.sort (CNote_melodic_tuple::pitch_compare
);
134 stopped_notes_
.sort (CNote_melodic_tuple::pitch_compare
);
138 while (i
< now_notes_
.size () && j
< stopped_notes_
.size ())
141 = Pitch::compare (*unsmob_pitch (now_notes_
[i
].req_l_
->get_mus_property ("pitch")),
142 *unsmob_pitch (stopped_notes_
[j
].req_l_
->get_mus_property ("pitch")));
146 (comp
< 0) ? i
++ : j
++;
153 /* don't go around recreating ties that were already
154 made. Not infallible. Due to reordering in sort (),
155 we will make the wrong ties when notenotes are
157 if (tie_count
> tie_p_arr_
.size ())
159 Audio_tie
* p
= new Audio_tie
;
160 p
->set_note (LEFT
, stopped_notes_
[j
].note_l_
);
161 p
->set_note (RIGHT
, now_notes_
[i
].note_l_
);
163 announce_element (Audio_element_info (p
, req_l_
));
171 if (!tie_p_arr_
.size ())
173 req_l_
->origin ()->warning (_ ("No ties were created!"));
179 Tie_performer::stop_translation_timestep ()
181 for (int i
=0; i
< now_notes_
.size (); i
++)
183 past_notes_pq_
.insert (now_notes_
[i
]);
187 for (int i
=0; i
< tie_p_arr_
.size (); i
++)
189 //play_element (tie_p_arr_[i]);
190 tie_p_arr_
[i
]->note_l_drul_
[RIGHT
]->tie_to (tie_p_arr_
[i
]->note_l_drul_
[LEFT
]);
196 Tie_performer::start_translation_timestep ()
200 Moment now
= now_mom ();
201 while (past_notes_pq_
.size () && past_notes_pq_
.front ().end_
< now
)
202 past_notes_pq_
.delmin ();
206 CNote_melodic_tuple::CNote_melodic_tuple ()
213 CNote_melodic_tuple::CNote_melodic_tuple (Audio_note
*h
, Melodic_req
*m
, Moment mom
)
221 CNote_melodic_tuple::pitch_compare (CNote_melodic_tuple
const&h1
,
222 CNote_melodic_tuple
const &h2
)
224 SCM p1
= h1
.req_l_
->get_mus_property ("pitch");
225 SCM p2
= h2
.req_l_
->get_mus_property ("pitch");
226 return Pitch::compare (*unsmob_pitch (p1
),
231 CNote_melodic_tuple::time_compare (CNote_melodic_tuple
const&h1
,
232 CNote_melodic_tuple
const &h2
)
234 return (h1
.end_
- h2
.end_
).main_part_
.sign ();