]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-performer.cc
dd288025ddcbf8184f4a90d208ba4243a2295e5c
[lilypond.git] / lily / piano-pedal-performer.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2000--2012 Jan Nieuwenhuizen <janneke@gnu.org>
5
6   LilyPond is free software: you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation, either version 3 of the License, or
9   (at your option) any later version.
10
11   LilyPond is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with LilyPond.  If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include "performer.hh"
21
22 #include "audio-item.hh"
23 #include "international.hh"
24 #include "stream-event.hh"
25 #include "warn.hh"
26
27 #include "translator.icc"
28
29 enum Pedal_type {SOSTENUTO, SUSTAIN, UNA_CORDA, NUM_PEDAL_TYPES};
30
31 /**
32    perform Piano pedals
33 */
34 class Piano_pedal_performer : public Performer
35 {
36   struct Pedal_info
37   {
38     Stream_event *start_event_;
39     Drul_array<Stream_event *> event_drul_;
40   };
41
42 public:
43   TRANSLATOR_DECLARATIONS (Piano_pedal_performer);
44
45 protected:
46   virtual void initialize ();
47   static const char *pedal_type_str (int t);
48   void process_music ();
49   void stop_translation_timestep ();
50   void start_translation_timestep ();
51   DECLARE_TRANSLATOR_LISTENER (sustain);
52   DECLARE_TRANSLATOR_LISTENER (una_corda);
53   DECLARE_TRANSLATOR_LISTENER (sostenuto);
54 private:
55   vector<Audio_piano_pedal *> audios_;
56   Pedal_info info_alist_[NUM_PEDAL_TYPES];
57 };
58
59 Piano_pedal_performer::Piano_pedal_performer ()
60 {
61 }
62
63 const char *
64 Piano_pedal_performer::pedal_type_str (int t)
65 {
66   switch (t)
67     {
68     case SOSTENUTO:
69       return "Sostenuto";
70     case SUSTAIN:
71       return "Sustain";
72     case UNA_CORDA:
73       return "UnaCorda";
74     default:
75       programming_error ("Unknown pedal type");
76       return 0;
77     }
78 }
79
80 void
81 Piano_pedal_performer::initialize ()
82 {
83   Pedal_info *p = info_alist_;
84
85   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
86     {
87       p->event_drul_[START] = 0;
88       p->event_drul_[STOP] = 0;
89       p->start_event_ = 0;
90     }
91 }
92
93 void
94 Piano_pedal_performer::process_music ()
95 {
96   Pedal_info *p = info_alist_;
97
98   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
99     {
100       string pedal_type = pedal_type_str (i);
101       if (p->event_drul_[STOP])
102         {
103           if (!p->start_event_)
104             p->event_drul_[STOP]->origin ()->warning (_f ("cannot find start of piano pedal: `%s'", pedal_type));
105           else
106             {
107               Audio_piano_pedal *a = new Audio_piano_pedal;
108               a->type_string_ = pedal_type;
109               a->dir_ = STOP;
110               audios_.push_back (a);
111               Audio_element_info info (a, p->event_drul_[STOP]);
112               announce_element (info);
113             }
114           p->start_event_ = 0;
115         }
116
117       if (p->event_drul_[START])
118         {
119           p->start_event_ = p->event_drul_[START];
120           Audio_piano_pedal *a = new Audio_piano_pedal;
121           a->type_string_ = pedal_type;
122           a->dir_ = START;
123           audios_.push_back (a);
124           Audio_element_info info (a, p->event_drul_[START]);
125           announce_element (info);
126         }
127       p->event_drul_[START] = 0;
128       p->event_drul_[STOP] = 0;
129     }
130 }
131
132 void
133 Piano_pedal_performer::stop_translation_timestep ()
134 {
135   audios_.clear ();
136 }
137
138 void
139 Piano_pedal_performer::start_translation_timestep ()
140 {
141   Pedal_info *p = info_alist_;
142   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
143     {
144       p->event_drul_[STOP] = 0;
145       p->event_drul_[START] = 0;
146     }
147 }
148
149 IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sostenuto);
150 void
151 Piano_pedal_performer::listen_sostenuto (Stream_event *r)
152 {
153   Direction d = to_dir (r->get_property ("span-direction"));
154   info_alist_[SOSTENUTO].event_drul_[d] = r;
155 }
156
157 IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sustain);
158 void
159 Piano_pedal_performer::listen_sustain (Stream_event *r)
160 {
161   Direction d = to_dir (r->get_property ("span-direction"));
162   info_alist_[SUSTAIN].event_drul_[d] = r;
163 }
164
165 IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, una_corda);
166 void
167 Piano_pedal_performer::listen_una_corda (Stream_event *r)
168 {
169   Direction d = to_dir (r->get_property ("span-direction"));
170   info_alist_[UNA_CORDA].event_drul_[d] = r;
171 }
172
173 ADD_TRANSLATOR (Piano_pedal_performer,
174                 /* doc */
175                 "",
176
177                 /* create */
178                 "",
179
180                 /* read */
181                 "",
182
183                 /* write */
184                 ""
185                );