]> git.donarmstrong.com Git - lilypond.git/blob - lily/span-dynamic-performer.cc
partial: 1.3.31.jcn
[lilypond.git] / lily / span-dynamic-performer.cc
1 /*
2   span-dynamic-performer.cc -- implement Span_dynamic_performer
3
4   source file of the GNU LilyPond music typesetter
5
6   (c)  2000 Jan Nieuwenhuizen <janneke@gnu.org>
7 */
8
9 #include "performer.hh"
10 #include "command-request.hh"
11 #include "musical-request.hh"
12 #include "audio-item.hh"
13
14 struct Audio_dynamic_tuple
15 {
16   Audio_dynamic* audio_l_;
17   Moment mom_;
18 };
19
20 /**
21    handle perform span-dynamics
22  */
23 class Span_dynamic_performer : public Performer
24 {
25 public:
26   VIRTUAL_COPY_CONS (Translator);
27   
28   Span_dynamic_performer ();
29
30 protected:
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 ();
35
36 private:
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_;
41
42   // BURP
43   Drul_array<Moment> done_moment_drul_;
44   Drul_array<int> done_volume_drul_;
45   Array<Audio_dynamic_tuple> done_dynamic_tuple_arr_;
46
47   Audio_dynamic* audio_p_;
48 };
49
50 ADD_THIS_TRANSLATOR (Span_dynamic_performer);
51
52 Span_dynamic_performer::Span_dynamic_performer ()
53 {
54   request_drul_[START] = request_drul_[STOP] = 0;
55   volume_drul_[START] = volume_drul_[STOP] = 0;
56   audio_p_ = 0;
57 }
58
59 void
60 Span_dynamic_performer::acknowledge_element (Audio_element_info i)
61 {
62   if (Audio_dynamic * d = dynamic_cast <Audio_dynamic*> (i.elem_l_))
63     {
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_;
68 #if 0
69       Audio_dynamic_tuple a = { d, now_mom () };
70       dynamic_tuple_arr_.push (a);
71 #endif
72     }
73 }
74
75 void
76 Span_dynamic_performer::do_process_requests ()
77 {
78   if (request_drul_[START])
79     {
80       audio_p_ = new Audio_dynamic (volume_drul_[START]);
81       Audio_element_info info (audio_p_, 0);
82       announce_element (info);
83
84       Audio_dynamic_tuple a = { audio_p_, now_mom () };
85       dynamic_tuple_arr_.push (a);
86     }
87
88   if (done_dynamic_tuple_arr_.size ())
89     {
90       if (done_volume_drul_[STOP])
91         {
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++)
95             {
96               Real volume =
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;
101             }
102         }
103       done_dynamic_tuple_arr_.clear ();
104     }
105
106   if (request_drul_[STOP])
107     {
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;
117     }
118 }
119
120 void
121 Span_dynamic_performer::do_pre_move_processing ()
122 {
123   if (audio_p_)
124     {
125       play_element (audio_p_);
126       audio_p_ = 0;
127     }
128 }
129
130 bool
131 Span_dynamic_performer::do_try_music (Music* r)
132 {
133   if (Span_req * s = dynamic_cast<Span_req*>(r))
134     {
135       if (s-> span_type_str_ != "crescendo"
136           && s->span_type_str_ != "decrescendo")
137         return false;
138       
139       Direction d = s->span_dir_;
140
141       if (d == STOP && !request_drul_[START])
142         {
143           r->warning (_ ("No (de)crescendo to end"));
144           return false;
145         }
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];
150       return true;
151     }
152   return false;
153 }