]> git.donarmstrong.com Git - lilypond.git/blob - lily/piano-pedal-performer.cc
Web-ja: update introduction
[lilypond.git] / lily / piano-pedal-performer.cc
1 /*
2   This file is part of LilyPond, the GNU music typesetter.
3
4   Copyright (C) 2000--2015 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   void listen_sustain (Stream_event *);
52   void listen_una_corda (Stream_event *);
53   void listen_sostenuto (Stream_event *);
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 (Context *c)
60   : Performer (c)
61 {
62 }
63
64 const char *
65 Piano_pedal_performer::pedal_type_str (int t)
66 {
67   switch (t)
68     {
69     case SOSTENUTO:
70       return "Sostenuto";
71     case SUSTAIN:
72       return "Sustain";
73     case UNA_CORDA:
74       return "UnaCorda";
75     default:
76       programming_error ("Unknown pedal type");
77       return 0;
78     }
79 }
80
81 void
82 Piano_pedal_performer::initialize ()
83 {
84   Pedal_info *p = info_alist_;
85
86   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
87     {
88       p->event_drul_[START] = 0;
89       p->event_drul_[STOP] = 0;
90       p->start_event_ = 0;
91     }
92 }
93
94 void
95 Piano_pedal_performer::process_music ()
96 {
97   Pedal_info *p = info_alist_;
98
99   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
100     {
101       string pedal_type = pedal_type_str (i);
102       if (p->event_drul_[STOP])
103         {
104           if (!p->start_event_)
105             p->event_drul_[STOP]->origin ()->warning (_f ("cannot find start of piano pedal: `%s'", pedal_type));
106           else
107             {
108               Audio_piano_pedal *a = new Audio_piano_pedal;
109               a->type_string_ = pedal_type;
110               a->dir_ = STOP;
111               audios_.push_back (a);
112               Audio_element_info info (a, p->event_drul_[STOP]);
113               announce_element (info);
114             }
115           p->start_event_ = 0;
116         }
117
118       if (p->event_drul_[START])
119         {
120           p->start_event_ = p->event_drul_[START];
121           Audio_piano_pedal *a = new Audio_piano_pedal;
122           a->type_string_ = pedal_type;
123           a->dir_ = START;
124           audios_.push_back (a);
125           Audio_element_info info (a, p->event_drul_[START]);
126           announce_element (info);
127         }
128       p->event_drul_[START] = 0;
129       p->event_drul_[STOP] = 0;
130     }
131 }
132
133 void
134 Piano_pedal_performer::stop_translation_timestep ()
135 {
136   audios_.clear ();
137 }
138
139 void
140 Piano_pedal_performer::start_translation_timestep ()
141 {
142   Pedal_info *p = info_alist_;
143   for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++)
144     {
145       p->event_drul_[STOP] = 0;
146       p->event_drul_[START] = 0;
147     }
148 }
149
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 void
158 Piano_pedal_performer::listen_sustain (Stream_event *r)
159 {
160   Direction d = to_dir (r->get_property ("span-direction"));
161   info_alist_[SUSTAIN].event_drul_[d] = r;
162 }
163
164 void
165 Piano_pedal_performer::listen_una_corda (Stream_event *r)
166 {
167   Direction d = to_dir (r->get_property ("span-direction"));
168   info_alist_[UNA_CORDA].event_drul_[d] = r;
169 }
170
171 void
172 Piano_pedal_performer::boot ()
173 {
174   ADD_LISTENER (Piano_pedal_performer, sostenuto);
175   ADD_LISTENER (Piano_pedal_performer, sustain);
176   ADD_LISTENER (Piano_pedal_performer, una_corda);
177 }
178
179 ADD_TRANSLATOR (Piano_pedal_performer,
180                 /* doc */
181                 "",
182
183                 /* create */
184                 "",
185
186                 /* read */
187                 "",
188
189                 /* write */
190                 ""
191                );