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_;
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_music ();
34 virtual void do_pre_move_processing ();
35 virtual void do_post_move_processing ();
38 Audio_dynamic* audio_p_;
39 Span_req* span_start_req_l_;
40 Drul_array<Span_req*> span_req_l_drul_;
41 Array<Audio_dynamic_tuple> dynamic_tuple_arr_;
42 Array<Audio_dynamic_tuple> finished_dynamic_tuple_arr_;
43 Direction finished_dir_;
46 ADD_THIS_TRANSLATOR (Span_dynamic_performer);
48 Span_dynamic_performer::Span_dynamic_performer ()
50 span_req_l_drul_[START] = 0;
51 span_req_l_drul_[STOP] = 0;
52 span_start_req_l_ = 0;
57 Span_dynamic_performer::acknowledge_element (Audio_element_info i)
59 if (Audio_dynamic * d = dynamic_cast <Audio_dynamic*> (i.elem_l_))
61 Audio_dynamic_tuple a = { d, now_mom () };
62 if (!span_req_l_drul_[START])
63 dynamic_tuple_arr_.clear ();
64 dynamic_tuple_arr_.push (a);
65 if (finished_dynamic_tuple_arr_.size ())
66 finished_dynamic_tuple_arr_.push (a);
71 Span_dynamic_performer::do_process_music ()
73 if (finished_dynamic_tuple_arr_.size () > 1
74 && finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_)
76 Real start_volume = finished_dynamic_tuple_arr_[0].audio_l_->volume_i_;
77 Real dv = finished_dynamic_tuple_arr_.top ().audio_l_->volume_i_
81 Catch and fix the case of:
85 f cresc. -- -- -- -- -- pp
87 Actually, we should provide a non-displayed dynamic/volume setting,
88 to set volume to 'ff' just before the pp.
90 if (!dv || sign (dv) != finished_dir_)
92 // urg. about one volume step
93 dv = (int)finished_dir_ * 13;
95 start_volume = finished_dynamic_tuple_arr_.top
96 ().audio_l_->volume_i_ - dv;
98 Moment start_mom = finished_dynamic_tuple_arr_[0].mom_;
99 Moment dt = finished_dynamic_tuple_arr_.top ().mom_ - start_mom;
100 for (int i=0; i < finished_dynamic_tuple_arr_.size (); i++)
102 Audio_dynamic_tuple* a = &finished_dynamic_tuple_arr_[i];
103 Real volume = start_volume + dv * (Real)(a->mom_ - start_mom)
105 a->audio_l_->volume_i_ = (int)volume;
107 finished_dynamic_tuple_arr_.clear ();
110 if (span_req_l_drul_[STOP])
112 if (!span_start_req_l_)
114 span_req_l_drul_[STOP]->warning (_ ("can't find start of (de)crescendo"));
118 span_start_req_l_ = 0;
119 finished_dynamic_tuple_arr_ = dynamic_tuple_arr_;
120 finished_dir_ = span_req_l_drul_[STOP]->span_type_str_ == "crescendo"
122 dynamic_tuple_arr_.clear ();
123 if (finished_dynamic_tuple_arr_.size ())
124 dynamic_tuple_arr_.push (finished_dynamic_tuple_arr_.top ());
128 if (span_req_l_drul_[START])
130 span_start_req_l_ = span_req_l_drul_[START];
131 audio_p_ = new Audio_dynamic (0);
132 Audio_element_info info (audio_p_, 0);
133 announce_element (info);
135 Audio_dynamic_tuple a = { audio_p_, now_mom () };
136 dynamic_tuple_arr_.push (a);
141 Span_dynamic_performer::do_pre_move_processing ()
145 play_element (audio_p_);
151 Span_dynamic_performer::do_post_move_processing ()
153 span_req_l_drul_[STOP] = 0;
154 span_req_l_drul_[START] = 0;
158 Span_dynamic_performer::do_try_music (Music* r)
160 if (Span_req * s = dynamic_cast<Span_req*>(r))
162 if (s-> span_type_str_ == "crescendo"
163 || s->span_type_str_ == "decrescendo")
165 span_req_l_drul_[s->span_dir_] = s;