From ed2130db4ef8bc48d2ec394747538ee28062e0bd Mon Sep 17 00:00:00 2001 From: Han-Wen Nienhuys Date: Sun, 7 Jan 2007 02:07:07 +0100 Subject: [PATCH] Fix #86; Fix midi dynamics coverage. New_dynamic_performer, unified handling of absolute and span dynamics. Conflicts: lily/audio-item.cc lily/dynamic-performer.cc lily/span-dynamic-performer.cc --- input/regression/midi-dynamics.ly | 24 +++++++++ lily/audio-column.cc | 12 ++--- lily/audio-item.cc | 82 +++++++++++++++++++++++++++++-- lily/include/audio-column.hh | 8 +-- lily/include/audio-item.hh | 18 ++++++- lily/midi-walker.cc | 8 +-- lily/score-performer.cc | 6 +-- ly/performer-init.ly | 4 +- 8 files changed, 138 insertions(+), 24 deletions(-) create mode 100644 input/regression/midi-dynamics.ly diff --git a/input/regression/midi-dynamics.ly b/input/regression/midi-dynamics.ly new file mode 100644 index 0000000000..edff9c2f7a --- /dev/null +++ b/input/regression/midi-dynamics.ly @@ -0,0 +1,24 @@ +\header { + + texidoc = "Midi also handles crescendo and decrescendo, either + starting and ending from specified or unspecified sound level." + +} + +\version "2.11.10" + +\score { + \relative { + + \set midiMinimumVolume = #0.0 + \set midiMaximumVolume = #1.0 + c\ff c\pppp + c\ff\> c c c c\!\pppp + + c\< c c c c\! \ff + + c\> c c c \! + } + \midi {} + \layout{} +} diff --git a/lily/audio-column.cc b/lily/audio-column.cc index d0a36518a5..6365305675 100644 --- a/lily/audio-column.cc +++ b/lily/audio-column.cc @@ -11,9 +11,9 @@ #include "audio-item.hh" #include "performance.hh" -Audio_column::Audio_column (Moment at_mom) +Audio_column::Audio_column (Moment when) { - at_mom_ = at_mom; + when_ = when; } void @@ -24,14 +24,14 @@ Audio_column::add_audio_item (Audio_item *l) } Moment -Audio_column::at_mom () const +Audio_column::when () const { - return at_mom_; + return when_; } void -Audio_column::offset_at_mom (Moment m) +Audio_column::offset_when (Moment m) { - at_mom_ += m; + when_ += m; } diff --git a/lily/audio-item.cc b/lily/audio-item.cc index fe8c5539e1..ecff754c1b 100644 --- a/lily/audio-item.cc +++ b/lily/audio-item.cc @@ -16,6 +16,17 @@ Audio_instrument::Audio_instrument (string instrument_string) str_ = instrument_string; } +void +Audio_item::render () +{ +} + +Audio_column * +Audio_item::get_column () const +{ + return audio_column_; +} + Audio_item::Audio_item () { audio_column_ = 0; @@ -47,12 +58,77 @@ Audio_key::Audio_key (int acc, bool major) major_ = major; } -Audio_dynamic::Audio_dynamic (Real volume) +Audio_dynamic::Audio_dynamic () +{ + volume_ = -1; +} + +Audio_span_dynamic::Audio_span_dynamic () +{ + grow_dir_ = CENTER; +} + +void +Audio_span_dynamic::add_absolute (Audio_dynamic *d) +{ + assert (d); + dynamics_.push_back (d); +} + +static Real +moment2real (Moment m) { - volume_ = volume; + return m.main_part_.to_double () + + 0.1 * m.grace_part_.to_double (); } -Audio_tempo::Audio_tempo (int per_minute_4_i) + +void +Audio_span_dynamic::render () +{ + if (dynamics_.size () <= 1) + return ; + + assert (dynamics_[0]->volume_ >= 0); + + if (dynamics_.back ()->volume_ > 0 + && sign (dynamics_.back ()->volume_ - dynamics_[0]->volume_) != grow_dir_) + { + dynamics_.erase (dynamics_.end () - 1); + assert (dynamics_.back ()->volume_ < 0); + } + + if (dynamics_.size () <= 1) + return ; + + Real delta_v = grow_dir_ * 0.1; + + Real start_v = dynamics_[0]->volume_; + if (dynamics_.back ()->volume_ < 0) + dynamics_.back ()->volume_ = max (min (start_v + grow_dir_ * 0.25, 1.0), 0.0); + + delta_v = dynamics_.back ()->volume_ - dynamics_[0]->volume_; + + Moment start = dynamics_[0]->get_column ()->when (); + + Real total_t = moment2real (dynamics_.back ()->get_column ()->when () - start); + + for (vsize i = 1; i < dynamics_.size(); i ++) + { + Moment dt_moment = dynamics_[i]->get_column ()->when () + - start; + + Real dt = moment2real (dt_moment); + + Real v = start_v + delta_v * (dt / total_t); + + dynamics_[i]->volume_ = v; + } +} + + + +Audio_tempo::Audio_tempo (int per_minute_4) { per_minute_4_ = per_minute_4_i; } diff --git a/lily/include/audio-column.hh b/lily/include/audio-column.hh index 1cc827a276..1d0fb5ca18 100644 --- a/lily/include/audio-column.hh +++ b/lily/include/audio-column.hh @@ -19,21 +19,21 @@ class Audio_column : public Audio_element { public: - Audio_column (Moment at_mom); + Audio_column (Moment when); void add_audio_item (Audio_item *i); - Moment at_mom () const; + Moment when () const; vector audio_items_; protected: - void offset_at_mom (Moment m); + void offset_when (Moment m); friend class Score_performer; private: Audio_column (Audio_column const &); - Moment at_mom_; + Moment when_; }; #endif // AUDIO_COLUMN_HH diff --git a/lily/include/audio-item.hh b/lily/include/audio-item.hh index 11f3cd31f5..d26e567bff 100644 --- a/lily/include/audio-item.hh +++ b/lily/include/audio-item.hh @@ -21,7 +21,10 @@ class Audio_item : public Audio_element public: Audio_item (); Audio_column *audio_column_; + Audio_column *get_column () const; + virtual void render (); + private: Audio_item (Audio_item const &); Audio_item &operator = (Audio_item const &); @@ -30,11 +33,24 @@ private: class Audio_dynamic : public Audio_item { public: - Audio_dynamic (Real volume); + Audio_dynamic (); Real volume_; }; +class Audio_span_dynamic : public Audio_element +{ +public: + Direction grow_dir_; + vector dynamics_; + + + virtual void render (); + void add_absolute (Audio_dynamic*); + Audio_span_dynamic (); +}; + + class Audio_key : public Audio_item { public: diff --git a/lily/midi-walker.cc b/lily/midi-walker.cc index 2979c9380c..20dfb45ef5 100644 --- a/lily/midi-walker.cc +++ b/lily/midi-walker.cc @@ -57,7 +57,7 @@ void Midi_walker::do_start_note (Midi_note *note) { Audio_item *ptr = (*items_)[index_]; - Moment stop_mom = note->get_length () + ptr->audio_column_->at_mom (); + Moment stop_mom = note->get_length () + ptr->audio_column_->when (); bool play_start = true; for (vsize i = 0; i < stop_note_queue.size (); i++) @@ -93,7 +93,7 @@ Midi_walker::do_start_note (Midi_note *note) stop_note_queue.insert (e); if (play_start) - output_event (ptr->audio_column_->at_mom (), note); + output_event (ptr->audio_column_->when (), note); } } @@ -142,7 +142,7 @@ void Midi_walker::process () { Audio_item *audio = (*items_)[index_]; - do_stop_notes (audio->audio_column_->at_mom ()); + do_stop_notes (audio->audio_column_->when ()); if (Midi_item *midi = Midi_item::get_midi (audio)) { @@ -156,7 +156,7 @@ Midi_walker::process () do_start_note (note); } else - output_event (audio->audio_column_->at_mom (), midi); + output_event (audio->audio_column_->when (), midi); } } diff --git a/lily/score-performer.cc b/lily/score-performer.cc index 34c5a1c78d..399298706e 100644 --- a/lily/score-performer.cc +++ b/lily/score-performer.cc @@ -115,7 +115,7 @@ Score_performer::one_time_step (SCM) { if (!skipping_) { - skip_start_mom_ = audio_column_->at_mom (); + skip_start_mom_ = audio_column_->when (); skipping_ = true; } } @@ -123,11 +123,11 @@ Score_performer::one_time_step (SCM) { if (skipping_) { - offset_mom_ -= audio_column_->at_mom () - skip_start_mom_; + offset_mom_ -= audio_column_->when () - skip_start_mom_; skipping_ = false; } - audio_column_->offset_at_mom (offset_mom_); + audio_column_->offset_when (offset_mom_); precomputed_recurse_over_translators (context (), PROCESS_MUSIC, UP); do_announces (); } diff --git a/ly/performer-init.ly b/ly/performer-init.ly index 24f0da2b81..23e96dae3c 100644 --- a/ly/performer-init.ly +++ b/ly/performer-init.ly @@ -30,9 +30,7 @@ \context { \type "Performer_group" \name Voice - % The order of the dynamic performers is significant: absolute dynamic events must override crescendo events in midi. - \consists "Span_dynamic_performer" - \consists "Dynamic_performer" + \consists "New_dynamic_performer" \consists "Tie_performer" \consists "Piano_pedal_performer" \consists "Note_performer" -- 2.39.5