/* piano-pedal-performer.cc -- implement Piano_pedal_performer source file of the GNU LilyPond music typesetter (c) 2000--2006 Jan Nieuwenhuizen */ #include "performer.hh" #include "audio-item.hh" #include "international.hh" #include "stream-event.hh" #include "warn.hh" #include "translator.icc" #define SOSTENUTO 0 #define SUSTAIN 1 #define UNA_CORDA 2 #define NUM_PEDAL_TYPES 3 /** perform Piano pedals */ class Piano_pedal_performer : public Performer { struct Pedal_info { Stream_event *start_event_; Drul_array event_drul_; }; public: TRANSLATOR_DECLARATIONS (Piano_pedal_performer); protected: virtual void initialize (); static const char *pedal_type_str (int t); void process_music (); void stop_translation_timestep (); void start_translation_timestep (); DECLARE_TRANSLATOR_LISTENER (sustain); DECLARE_TRANSLATOR_LISTENER (una_corda); DECLARE_TRANSLATOR_LISTENER (sostenuto); private: vector audios_; Pedal_info info_alist_[NUM_PEDAL_TYPES]; }; Piano_pedal_performer::Piano_pedal_performer () { } const char * Piano_pedal_performer::pedal_type_str (int t) { switch (t) { case SOSTENUTO: return "Sostenuto"; case SUSTAIN: return "Sustain"; case UNA_CORDA: return "UnaCorda"; default: programming_error ("Unknown pedal type"); return 0; } } void Piano_pedal_performer::initialize () { Pedal_info *p = info_alist_; for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++) { p->event_drul_[START] = 0; p->event_drul_[STOP] = 0; p->start_event_ = 0; } } void Piano_pedal_performer::process_music () { Pedal_info *p = info_alist_; for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++) { if (p->event_drul_[STOP]) { if (!p->start_event_) p->event_drul_[STOP]->origin ()->warning (_f ("can't find start of piano pedal: `%s'", pedal_type_str (i))); else { Audio_piano_pedal *a = new Audio_piano_pedal; a->type_string_ = string (pedal_type_str (i)); a->dir_ = STOP; audios_.push_back (a); Audio_element_info info(a, p->event_drul_[STOP]); announce_element (info); } p->start_event_ = 0; } if (p->event_drul_[START]) { p->start_event_ = p->event_drul_[START]; Audio_piano_pedal *a = new Audio_piano_pedal; a->type_string_ = string (pedal_type_str (i)); a->dir_ = START; audios_.push_back (a); Audio_element_info info(a, p->event_drul_[START]); announce_element (info); } p->event_drul_[START] = 0; p->event_drul_[STOP] = 0; } } void Piano_pedal_performer::stop_translation_timestep () { for (vsize i = 0; i < audios_.size (); i++) play_element (audios_[i]); audios_.clear (); } void Piano_pedal_performer::start_translation_timestep () { Pedal_info *p = info_alist_; for (int i = 0; i < NUM_PEDAL_TYPES; i++, p++) { p->event_drul_[STOP] = 0; p->event_drul_[START] = 0; } } IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sostenuto); void Piano_pedal_performer::listen_sostenuto (Stream_event *r) { Direction d = to_dir (r->get_property ("span-direction")); info_alist_[SOSTENUTO].event_drul_[d] = r; } IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, sustain); void Piano_pedal_performer::listen_sustain (Stream_event *r) { Direction d = to_dir (r->get_property ("span-direction")); info_alist_[SUSTAIN].event_drul_[d] = r; } IMPLEMENT_TRANSLATOR_LISTENER (Piano_pedal_performer, una_corda); void Piano_pedal_performer::listen_una_corda (Stream_event *r) { Direction d = to_dir (r->get_property ("span-direction")); info_alist_[UNA_CORDA].event_drul_[d] = r; } ADD_TRANSLATOR (Piano_pedal_performer, "", "", "pedal-event", "", "");