]> git.donarmstrong.com Git - lilypond.git/commitdiff
Fix #86; Fix midi dynamics coverage.
authorHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 7 Jan 2007 01:07:07 +0000 (02:07 +0100)
committerHan-Wen Nienhuys <hanwen@xs4all.nl>
Sun, 7 Jan 2007 01:07:07 +0000 (02:07 +0100)
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 [new file with mode: 0644]
lily/audio-column.cc
lily/audio-item.cc
lily/include/audio-column.hh
lily/include/audio-item.hh
lily/midi-walker.cc
lily/score-performer.cc
ly/performer-init.ly

diff --git a/input/regression/midi-dynamics.ly b/input/regression/midi-dynamics.ly
new file mode 100644 (file)
index 0000000..edff9c2
--- /dev/null
@@ -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{}
+}
index d0a36518a573584bcee77c14d75fa0b75a78a5c5..6365305675938e91ac6741c408af402d03469bea 100644 (file)
@@ -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;
 }
 
index fe8c5539e1c6e593a339553132a0abbd889e7277..ecff754c1be67bd076f64b6ebdb1f3958b694cc5 100644 (file)
@@ -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;
 }
index 1cc827a2767fff90abde602dbaf450f40af3f493..1d0fb5ca18d6fb3e64268225393488682de0d569 100644 (file)
 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_item*> 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
index 11f3cd31f5b90f2211578e0ed5f80c44968f415b..d26e567bff8e8c67fa84f0350461bea9af199918 100644 (file)
@@ -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<Audio_dynamic*> dynamics_;
+
+
+  virtual void render ();
+  void add_absolute (Audio_dynamic*);
+  Audio_span_dynamic ();
+};
+
+
 class Audio_key : public Audio_item
 {
 public:
index 2979c9380ce1127a3d6687180840ca1a70315730..20dfb45ef54e251d8d407ce31bfcb4a79d5f5353 100644 (file)
@@ -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);
     }
 }
 
index 34c5a1c78d8f26dea0af75a425f6ae3f09b4706b..399298706ec0d860580c3e2300acb61a98697a8c 100644 (file)
@@ -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 ();
     }
index 24f0da2b81b567496217cbce4f1b29c883a3bf0c..23e96dae3ce98fa4b10b86c3052dc5f6793aea06 100644 (file)
@@ -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"