From: Han-Wen Nienhuys Date: Sun, 7 Jan 2007 01:06:53 +0000 (+0100) Subject: really add new-dynamic-performer.cc X-Git-Tag: release/2.11.10-1~33 X-Git-Url: https://git.donarmstrong.com/?a=commitdiff_plain;h=75b2a16e79b94aa9c9f0d7519dee493cc699fee1;p=lilypond.git really add new-dynamic-performer.cc --- diff --git a/lily/new-dynamic-performer.cc b/lily/new-dynamic-performer.cc new file mode 100644 index 0000000000..7afc555c7a --- /dev/null +++ b/lily/new-dynamic-performer.cc @@ -0,0 +1,213 @@ +/* + dynamic-performer.cc -- implement New_dynamic_performer + + source file of the GNU LilyPond music typesetter + + (c) 2000--2006 Jan Nieuwenhuizen +*/ + +#include "performer.hh" +#include "audio-item.hh" +#include "stream-event.hh" + +#include "translator.icc" + +/* + TODO: + + handle multiple events + + perform absolute (text) dynamics +*/ +class New_dynamic_performer : public Performer +{ +public: + TRANSLATOR_DECLARATIONS (New_dynamic_performer); +protected: + void stop_translation_timestep (); + void process_music (); + Real equalize_volume (Real); + + DECLARE_TRANSLATOR_LISTENER (decrescendo); + DECLARE_TRANSLATOR_LISTENER (crescendo); + DECLARE_TRANSLATOR_LISTENER (absolute_dynamic); +private: + Stream_event *script_event_; + Drul_array span_events_; + Drul_array grow_dir_; + Real last_volume_; + Audio_dynamic *absolute_; + Audio_span_dynamic *span_dynamic_; + Audio_span_dynamic *finished_span_dynamic_; +}; + +New_dynamic_performer::New_dynamic_performer () +{ + last_volume_ = 0.5; + script_event_ = 0; + absolute_ = 0; + span_events_[LEFT] = + span_events_[RIGHT] = 0; + span_dynamic_ = 0; + finished_span_dynamic_ = 0; +} + +Real +New_dynamic_performer::equalize_volume (Real volume) +{ + /* + properties override default equaliser setting + */ + SCM min = get_property ("midiMinimumVolume"); + SCM max = get_property ("midiMaximumVolume"); + if (scm_is_number (min) || scm_is_number (max)) + { + Interval iv (0, 1); + if (scm_is_number (min)) + iv[MIN] = scm_to_double (min); + if (scm_is_number (max)) + iv[MAX] = scm_to_double (max); + volume = iv[MIN] + iv.length () * volume; + } + else + { + /* + urg, code duplication:: staff_performer + */ + SCM s = get_property ("midiInstrument"); + + if (!scm_is_string (s)) + s = get_property ("instrumentName"); + + if (!scm_is_string (s)) + s = scm_from_locale_string ("piano"); + + SCM eq = get_property ("instrumentEqualizer"); + if (ly_is_procedure (eq)) + s = scm_call_1 (eq, s); + + if (is_number_pair (s)) + { + Interval iv = ly_scm2interval (s); + volume = iv[MIN] + iv.length () * volume; + } + } + return volume; +} + + +void +New_dynamic_performer::process_music () +{ + if (span_events_[STOP] || script_event_) + { + finished_span_dynamic_ = span_dynamic_; + span_dynamic_ = 0; + } + + if (span_events_[START]) + { + span_dynamic_ = new Audio_span_dynamic(); + announce_element (Audio_element_info (span_dynamic_, span_events_[START])); + + span_dynamic_->grow_dir_ = grow_dir_[START]; + } + + if (script_event_ + || span_dynamic_ + || finished_span_dynamic_) + { + absolute_ = new Audio_dynamic (); + + if (script_event_) + { + SCM proc = get_property ("dynamicAbsoluteVolumeFunction"); + + SCM svolume = SCM_EOL; + if (ly_is_procedure (proc)) + { + // urg + svolume = scm_call_1 (proc, script_event_->get_property ("text")); + } + + Real volume = robust_scm2double (svolume, 0.5); + + last_volume_ + = absolute_->volume_ = equalize_volume (volume); + } + + Audio_element_info info (absolute_, script_event_); + announce_element (info); + } + + + if (span_dynamic_) + span_dynamic_->add_absolute (absolute_); + + if (finished_span_dynamic_) + finished_span_dynamic_->add_absolute (absolute_); +} + +void +New_dynamic_performer::stop_translation_timestep () +{ + if (finished_span_dynamic_) + { + finished_span_dynamic_->render (); + finished_span_dynamic_ = 0; + } + + + if (absolute_ && absolute_->volume_ < 0) + { + absolute_->volume_ = last_volume_; + } + else if (absolute_) + { + last_volume_ = absolute_->volume_; + } + + absolute_ = 0; + script_event_ = 0; + span_events_[LEFT] = + span_events_[RIGHT] = 0; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, decrescendo); +void +New_dynamic_performer::listen_decrescendo (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + span_events_[d] = r; + grow_dir_[d] = SMALLER; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, crescendo); +void +New_dynamic_performer::listen_crescendo (Stream_event *r) +{ + Direction d = to_dir (r->get_property ("span-direction")); + span_events_[d] = r; + grow_dir_[d] = BIGGER; +} + +IMPLEMENT_TRANSLATOR_LISTENER (New_dynamic_performer, absolute_dynamic); +void +New_dynamic_performer::listen_absolute_dynamic (Stream_event *r) +{ + if (!script_event_) + script_event_ = r; +} + +ADD_TRANSLATOR (New_dynamic_performer, + /* doc */ "", + /* create */ "", + + /* read */ + "dynamicAbsoluteVolumeFunction " + "instrumentEqualizer " + "midiMaximumVolume " + "midiMinimumVolume " + "midiInstrument " + , + /*writes*/"");