2 span-dynamic-performer.cc -- implement Span_dynamic_performer
4 source file of the GNU LilyPond music typesetter
6 (c) 2000 Jan Nieuwenhuizen <janneke@gnu.org>
9 #include "performer.hh"
10 #include "command-request.hh"
11 #include "musical-request.hh"
12 #include "audio-item.hh"
14 struct Audio_dynamic_tuple
16 Audio_dynamic* audio_l_;
21 handle perform span-dynamics
23 class Span_dynamic_performer : public Performer
26 VIRTUAL_COPY_CONS (Translator);
28 Span_dynamic_performer ();
31 virtual bool do_try_music (Music* req_l);
32 virtual void acknowledge_element (Audio_element_info);
33 virtual void do_process_requests ();
34 virtual void do_pre_move_processing ();
37 Drul_array<Span_req*> request_drul_;
38 Drul_array<Moment> moment_drul_;
39 Drul_array<int> volume_drul_;
40 Array<Audio_dynamic_tuple> dynamic_tuple_arr_;
43 Drul_array<Moment> done_moment_drul_;
44 Drul_array<int> done_volume_drul_;
45 Array<Audio_dynamic_tuple> done_dynamic_tuple_arr_;
47 Audio_dynamic* audio_p_;
50 ADD_THIS_TRANSLATOR (Span_dynamic_performer);
52 Span_dynamic_performer::Span_dynamic_performer ()
54 request_drul_[START] = request_drul_[STOP] = 0;
55 volume_drul_[START] = volume_drul_[STOP] = 0;
60 Span_dynamic_performer::acknowledge_element (Audio_element_info i)
62 if (Audio_dynamic * d = dynamic_cast <Audio_dynamic*> (i.elem_l_))
64 Direction dir = volume_drul_[START] ? STOP : START;
65 volume_drul_[dir] = d->volume_i_;
66 if (done_dynamic_tuple_arr_.size ())
67 done_volume_drul_[STOP] = d->volume_i_;
69 Audio_dynamic_tuple a = { d, now_mom () };
70 dynamic_tuple_arr_.push (a);
76 Span_dynamic_performer::do_process_requests ()
78 if (request_drul_[START])
80 audio_p_ = new Audio_dynamic (volume_drul_[START]);
81 Audio_element_info info (audio_p_, 0);
82 announce_element (info);
84 Audio_dynamic_tuple a = { audio_p_, now_mom () };
85 dynamic_tuple_arr_.push (a);
88 if (done_dynamic_tuple_arr_.size ())
90 if (done_volume_drul_[STOP])
92 Real dv = done_volume_drul_[STOP] - done_volume_drul_[START];
93 Moment dt = done_moment_drul_[STOP] - done_moment_drul_[START];
94 for (int i=0; i < done_dynamic_tuple_arr_.size (); i++)
97 (done_volume_drul_[START]
98 + dv * (Real)(done_dynamic_tuple_arr_[i].mom_
99 - done_moment_drul_[START]) / (Real)dt);
100 done_dynamic_tuple_arr_[i].audio_l_->volume_i_ = (int)volume;
103 done_dynamic_tuple_arr_.clear ();
106 if (request_drul_[STOP])
108 done_dynamic_tuple_arr_ = dynamic_tuple_arr_;
109 dynamic_tuple_arr_.clear ();
110 done_volume_drul_[START] = volume_drul_[START];
111 done_volume_drul_[STOP] = volume_drul_[STOP];
112 done_moment_drul_[START] = moment_drul_[START];
113 done_moment_drul_[STOP] = moment_drul_[STOP];
114 request_drul_[STOP] = 0;
115 volume_drul_[START] = volume_drul_[STOP];
116 volume_drul_[STOP] = 0;
121 Span_dynamic_performer::do_pre_move_processing ()
125 play_element (audio_p_);
131 Span_dynamic_performer::do_try_music (Music* r)
133 if (Span_req * s = dynamic_cast<Span_req*>(r))
135 if (s-> span_type_str_ != "crescendo"
136 && s->span_type_str_ != "decrescendo")
139 Direction d = s->span_dir_;
141 if (d == STOP && !request_drul_[START])
143 r->warning (_ ("No (de)crescendo to end"));
146 request_drul_[d] = s;
147 moment_drul_[d] = now_mom ();
148 if (d == START && volume_drul_[STOP])
149 volume_drul_[START] = volume_drul_[STOP];