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_;
44 Direction finished_dir_;
47 ADD_THIS_TRANSLATOR (Span_dynamic_performer);
49 Span_dynamic_performer::Span_dynamic_performer ()
51 span_req_l_drul_[START] = 0;
52 span_req_l_drul_[STOP] = 0;
53 span_start_req_l_ = 0;
58 Span_dynamic_performer::acknowledge_element (Audio_element_info i)
60 if (Audio_dynamic * d = dynamic_cast <Audio_dynamic*> (i.elem_l_))
62 Audio_dynamic_tuple a = { d, now_mom () };
63 if (!span_req_l_drul_[START])
64 dynamic_tuple_arr_.clear ();
65 dynamic_tuple_arr_.push (a);
66 if (finished_dynamic_tuple_arr_.size ())
67 finished_dynamic_tuple_arr_.push (a);
72 Span_dynamic_performer::do_process_music ()
74 if (finished_dynamic_tuple_arr_.size () > 1
75 && finished_dynamic_tuple_arr_.top ().audio_l_->volume_)
77 Real start_volume = finished_dynamic_tuple_arr_[0].audio_l_->volume_;
78 Real dv = finished_dynamic_tuple_arr_.top ().audio_l_->volume_
82 Catch and fix the case of:
86 f cresc. -- -- -- -- -- pp
88 Actually, we should provide a non-displayed dynamic/volume setting,
89 to set volume to 'ff' just before the pp.
91 if (!dv || sign (dv) != finished_dir_)
93 // urg. 10%: about one volume step
94 dv = (Real)finished_dir_ * 0.1;
96 start_volume = finished_dynamic_tuple_arr_.top
97 ().audio_l_->volume_ - dv;
99 Moment start_mom = finished_dynamic_tuple_arr_[0].mom_;
100 Moment dt = finished_dynamic_tuple_arr_.top ().mom_ - start_mom;
101 for (int i=0; i < finished_dynamic_tuple_arr_.size (); i++)
103 Audio_dynamic_tuple* a = &finished_dynamic_tuple_arr_[i];
104 Real volume = start_volume + dv * (Real)(a->mom_ - start_mom)
106 a->audio_l_->volume_ = volume;
108 finished_dynamic_tuple_arr_.clear ();
111 if (span_req_l_drul_[STOP])
113 finished_dir_ = dir_;
114 if (!span_start_req_l_)
116 span_req_l_drul_[STOP]->warning (_ ("can't find start of (de)crescendo"));
120 span_start_req_l_ = 0;
121 finished_dynamic_tuple_arr_ = dynamic_tuple_arr_;
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 dir_ = span_req_l_drul_[START]->span_type_str_ == "crescendo"
132 span_start_req_l_ = span_req_l_drul_[START];
133 audio_p_ = new Audio_dynamic (0);
134 Audio_element_info info (audio_p_, 0);
135 announce_element (info);
137 Audio_dynamic_tuple a = { audio_p_, now_mom () };
138 dynamic_tuple_arr_.push (a);
143 Span_dynamic_performer::do_pre_move_processing ()
147 play_element (audio_p_);
153 Span_dynamic_performer::do_post_move_processing ()
155 span_req_l_drul_[STOP] = 0;
156 span_req_l_drul_[START] = 0;
160 Span_dynamic_performer::do_try_music (Music* r)
162 if (Span_req * s = dynamic_cast<Span_req*>(r))
164 if (s-> span_type_str_ == "crescendo"
165 || s->span_type_str_ == "decrescendo")
167 span_req_l_drul_[s->span_dir_] = s;