public:
TRANSLATOR_DECLARATIONS (Dynamic_performer);
protected:
+ virtual void acknowledge_audio_element (Audio_element_info info);
virtual void finalize ();
void stop_translation_timestep ();
void process_music ();
};
private:
+ vector<Audio_note *> notes_;
Stream_event *script_event_;
Drul_array<Stream_event *> span_events_;
Direction next_grow_dir_;
State state_;
};
-Dynamic_performer::Dynamic_performer ()
- : script_event_ (0),
+Dynamic_performer::Dynamic_performer (Context *c)
+ : Performer (c),
+ script_event_ (0),
next_grow_dir_ (CENTER),
depart_dir_ (CENTER),
state_ (STATE_INITIAL)
= span_events_[RIGHT] = 0;
}
+void
+Dynamic_performer::acknowledge_audio_element (Audio_element_info inf)
+{
+ // Keep track of the notes played in this translation time step so that they
+ // can be pointed to the current dynamic in stop_translation_timestep.
+ if (Audio_note *n = dynamic_cast<Audio_note *> (inf.elem_)) {
+ notes_.push_back (n);
+ }
+}
+
bool
Dynamic_performer::drive_state_machine (Direction next_grow_dir)
{
const Real vol_range = max_vol - min_vol;
- const Real near = minmax (depart_dir, start_vol, end_vol)
+ const Real near_vol = minmax (depart_dir, start_vol, end_vol)
+ depart_dir * near_padding * vol_range;
- const Real far = minmax (-depart_dir, start_vol, end_vol)
+ const Real far_vol = minmax (-depart_dir, start_vol, end_vol)
+ depart_dir * far_padding * vol_range;
- const Real depart_vol = minmax (depart_dir, near, far);
+ const Real depart_vol = minmax (depart_dir, near_vol, far_vol);
return max (min (depart_vol, max_vol), min_vol);
}
void
Dynamic_performer::stop_translation_timestep ()
{
+ // link notes to the current dynamic
+ if (!open_span_.dynamic_)
+ programming_error("no current dynamic");
+ else
+ {
+ for (vector<Audio_note *>::const_iterator ni = notes_.begin ();
+ ni != notes_.end (); ++ni)
+ {
+ (*ni)->dynamic_ = open_span_.dynamic_;
+ }
+ }
+ notes_.clear ();
+
script_event_ = 0;
span_events_[LEFT]
= span_events_[RIGHT] = 0;