New_dynamic_performer, unified handling of absolute and span dynamics.
Conflicts:
lily/audio-item.cc
lily/dynamic-performer.cc
lily/span-dynamic-performer.cc
--- /dev/null
+\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{}
+}
#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
}
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;
}
str_ = instrument_string;
}
+void
+Audio_item::render ()
+{
+}
+
+Audio_column *
+Audio_item::get_column () const
+{
+ return audio_column_;
+}
+
Audio_item::Audio_item ()
{
audio_column_ = 0;
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;
}
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
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 &);
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:
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++)
stop_note_queue.insert (e);
if (play_start)
- output_event (ptr->audio_column_->at_mom (), note);
+ output_event (ptr->audio_column_->when (), note);
}
}
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))
{
do_start_note (note);
}
else
- output_event (audio->audio_column_->at_mom (), midi);
+ output_event (audio->audio_column_->when (), midi);
}
}
{
if (!skipping_)
{
- skip_start_mom_ = audio_column_->at_mom ();
+ skip_start_mom_ = audio_column_->when ();
skipping_ = true;
}
}
{
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 ();
}
\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"