83 const auto blockMonotonicBeatRange = getMonotonicBeatRange (syncRange);
84 const auto duration = blockMonotonicBeatRange.v.getLength();
91 if (s.nextStatus == QueueState::stopQueued)
93 splitStatus.playing1 =
false;
96 s.lastPlayedRange = s.playedRange;
100 s.status = PlayState::stopped;
103 setState (std::move (s));
111 auto continuePlayingOrStopped = [&]
113 splitStatus.playing1 = s.status == PlayState::playing;
114 splitStatus.range1 = getBeatRange (syncRange);
115 splitStatus.playStartTime1 = s.playedRange ?
std::optional (s.playedRange->getStart())
119 s.playedRange = withEndExtended (*s.playedRange, duration);
121 if (s.playedMonotonicRange)
122 s.playedMonotonicRange =
MonotonicBeatRange { withEndExtended (s.playedMonotonicRange->v, duration) };
128 switch (*s.nextStatus)
130 case QueueState::playQueued:
134 if (s.nextEventTime->v <= blockMonotonicBeatRange.v.getStart())
136 splitStatus.playing1 =
true;
137 splitStatus.range1 = getBeatRange (syncRange);
138 splitStatus.playStartTime1 = splitStatus.range1.getStart();
141 s.lastPlayedRange = s.playedRange;
143 const auto numBeatsSinceLaunch = blockMonotonicBeatRange.v.getEnd() - s.nextEventTime->v;
145 s.playedRange = BeatRange::endingAt (splitStatus.range1.getEnd(), numBeatsSinceLaunch);
146 s.playedMonotonicRange =
MonotonicBeatRange { BeatRange::endingAt (blockMonotonicBeatRange.v.getEnd(), numBeatsSinceLaunch) };
147 s.status = PlayState::playing;
150 else if (blockMonotonicBeatRange.v.contains (s.nextEventTime->v))
152 const auto blockEditBeatRange = getBeatRange (syncRange);
154 splitStatus.playing1 = s.status == PlayState::playing;
155 splitStatus.range1 = blockEditBeatRange.withLength (s.nextEventTime->v - blockMonotonicBeatRange.v.getStart());
157 splitStatus.playing2 =
true;
158 splitStatus.range2 = { splitStatus.range1.getEnd(), blockEditBeatRange.getEnd() };
159 splitStatus.playStartTime2 = splitStatus.range2.getStart();
160 splitStatus.isSplit =
true;
162 assert(! splitStatus.range1.isEmpty());
163 assert(! splitStatus.range2.isEmpty());
166 s.lastPlayedRange = s.playedRange;
168 s.playedRange = { splitStatus.range2 };
169 s.playedMonotonicRange =
MonotonicBeatRange { BeatRange (s.nextEventTime->v, splitStatus.range2.getLength()) };
170 s.status = PlayState::playing;
176 continuePlayingOrStopped();
181 const auto blockEditBeatRange = getBeatRange (syncRange);
183 splitStatus.playing1 =
true;
184 splitStatus.range1 = blockEditBeatRange;
185 splitStatus.playStartTime1 = blockEditBeatRange.getStart();
187 s.playedRange = blockEditBeatRange;
188 s.playedMonotonicRange = getMonotonicBeatRange (syncRange);
189 s.status = PlayState::playing;
195 case QueueState::stopQueued:
197 if (s.status == PlayState::stopped)
199 splitStatus.playing1 =
false;
200 splitStatus.range1 = getBeatRange (syncRange);
208 else if (s.nextEventTime)
210 if (s.nextEventTime->v <= blockMonotonicBeatRange.v.getStart())
212 splitStatus.playing1 =
false;
213 splitStatus.range1 = getBeatRange (syncRange);
217 s.lastPlayedRange = s.playedRange;
221 s.status = PlayState::stopped;
224 else if (blockMonotonicBeatRange.v.contains (s.nextEventTime->v))
226 const auto blockEditBeatRange = getBeatRange (syncRange);
227 const auto playingDuration = s.nextEventTime->v - blockMonotonicBeatRange.v.getStart();
229 splitStatus.playing1 = s.status == PlayState::playing;
230 splitStatus.range1 = blockEditBeatRange.withLength (playingDuration);
232 splitStatus.playing2 =
false;
233 splitStatus.range2 = { splitStatus.range1.getEnd(), blockEditBeatRange.getEnd() };
235 splitStatus.isSplit =
true;
237 assert(! splitStatus.range1.isEmpty());
238 assert(! splitStatus.range2.isEmpty());
241 s.lastPlayedRange = withEndExtended (*s.playedRange, playingDuration);
245 s.status = PlayState::stopped;
251 continuePlayingOrStopped();
256 const auto blockEditBeatRange = getBeatRange (syncRange);
258 splitStatus.playing1 =
false;
259 splitStatus.range1 = blockEditBeatRange;
263 s.lastPlayedRange = s.playedRange;
267 s.status = PlayState::stopped;
277 continuePlayingOrStopped();
280 setState (std::move (s));