/*
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",
"", "");