2 #include <msp/core/algorithm.h>
8 Sequencer::Sequencer(float bpm):
13 set_beats_per_minute(bpm);
16 void Sequencer::set_beats_per_minute(float bpm)
18 secs_per_beat = Time::min/bpm;
21 void Sequencer::add_static_action(Action &act)
23 static_actions.push_back(&act);
26 void Sequencer::add_action(Action &act, float sb, float eb)
29 throw invalid_argument("Sequencer::add_action");
32 seq_act.action = &act;
33 seq_act.start_beat = sb;
34 seq_act.end_beat = eb;
35 auto i = find_if(segments, [=](const Segment &s){ return s.start_beat>sb; });
36 segments.insert(i, seq_act);
39 void Sequencer::start()
42 end = begin = segments.begin();
43 for(auto a: static_actions)
44 a->start(0, numeric_limits<float>::max());
45 float start_beat = beat;
47 advance_to(start_beat);
50 void Sequencer::seek(float b)
53 throw logic_error("Sequencer::seek");
61 void Sequencer::tick(const Time::TimeDelta &dt)
65 if(begin==segments.end())
68 advance_to(beat+dt/secs_per_beat);
71 void Sequencer::advance_to(float target_beat)
73 while(target_beat>next_event)
74 advance_to(next_event);
76 float prev_beat = beat;
79 while(end!=segments.end() && end->start_beat<=beat)
82 int ibeat = static_cast<int>(floor(beat));
83 bool do_beat = (ibeat!=static_cast<int>(floor(prev_beat)));
85 for(auto a: static_actions)
89 a->tick(beat, beat-prev_beat);
92 for(auto i=begin; i!=end; ++i)
94 if(i->start_beat>prev_beat)
95 i->action->start(i->start_beat, i->end_beat-i->start_beat);
97 i->action->beat(ibeat);
98 if(i->end_beat>=prev_beat)
100 float tick_beat = min(beat, i->end_beat);
101 i->action->tick(tick_beat, tick_beat-max(prev_beat, i->start_beat));
102 if(i->end_beat<=beat)
103 i->action->end(i->end_beat);
107 while(begin!=end && begin->end_beat<=beat)
110 if(target_beat>=next_event)
113 if(begin==segments.end())
114 signal_finished.emit();
117 void Sequencer::update_next_event()
119 next_event = numeric_limits<float>::max();
121 if(end!=segments.end())
122 next_event = min(next_event, end->start_beat);
124 for(auto i=begin; i!=end; ++i)
126 next_event = min(next_event, i->end_beat);
130 Sequencer::InterpolationAction::InterpolationAction(bool h):
136 void Sequencer::InterpolationAction::start(float b, float d)
140 interpolate(0.0f, 0.0f);
143 void Sequencer::InterpolationAction::tick(float b, float d)
147 float t = (b-start_beat)/duration;
148 float dt = d/duration;
153 dt = t-(3-2*dt)*dt*dt;
158 interpolate(1.0f, 1.0f);
161 void Sequencer::InterpolationAction::end(float)
163 interpolate(1.0f, 0.0f);