73 std::swap(m_beat_start_lookup, other.m_beat_start_lookup);
74 std::swap(m_time_start_lookup, other.m_time_start_lookup);
75 std::swap(m_avpTimingSegments, other.m_avpTimingSegments);
78 std::swap(ElapsedTimesAtAllRows, other.ElapsedTimesAtAllRows);
79 std::swap(ElapsedTimesAtNonEmptyRows, other.ElapsedTimesAtNonEmptyRows);
97 float elapsed_time{ 0 };
100 float warp_dest_out{ 0 };
101 int warp_begin_out{ -1 };
102 bool freeze_out{
false };
103 bool delay_out{
false };
108 unsigned int bpm{ 0 };
109 unsigned int warp{ 0 };
110 unsigned int stop{ 0 };
111 unsigned int delay{ 0 };
113 float last_time{ 0 };
114 float warp_destination{ 0 };
115 bool is_warping{
false };
134 using beat_start_lookup_t = std::vector<lookup_item_t>;
135 beat_start_lookup_t m_beat_start_lookup;
136 beat_start_lookup_t m_time_start_lookup;
138 void PrepareLookup();
139 void ReleaseLookup();
141 [[nodiscard]]
auto GetSegmentIndexAtRow(TimingSegmentType tst,
142 int row)
const -> int;
144 [[nodiscard]]
auto GetSegmentIndexAtBeat(TimingSegmentType tst,
145 float beat)
const ->
int
147 return GetSegmentIndexAtRow(tst, BeatToNoteRow(beat));
150 [[nodiscard]]
auto GetNextSegmentBeatAtRow(TimingSegmentType tst,
151 int row)
const -> float;
153 [[nodiscard]]
auto GetNextSegmentBeatAtBeat(TimingSegmentType tst,
154 float beat)
const ->
float
156 return GetNextSegmentBeatAtRow(tst, BeatToNoteRow(beat));
159 [[nodiscard]]
auto GetPreviousSegmentBeatAtRow(TimingSegmentType tst,
160 int row)
const -> float;
162 [[nodiscard]]
auto GetPreviousSegmentBeatAtBeat(TimingSegmentType tst,
163 float beat)
const ->
float
165 return GetPreviousSegmentBeatAtRow(tst, BeatToNoteRow(beat));
168 [[nodiscard]]
auto empty() const ->
bool;
170 void CopyRange(
int start_row,
172 TimingSegmentType copy_type,
175 void ShiftRange(
int start_row,
177 TimingSegmentType shift_type,
179 void ClearRange(
int start_row,
int end_row, TimingSegmentType clear_type);
191 float highest = FLT_MAX) const;
200 TimingSegmentType tst) const
211 TimingSegmentType tst) const
217#define DefineSegmentWithName(Seg, SegName, SegType) \
218 const Seg* Get##Seg##AtRow(int iNoteRow) const \
220 const TimingSegment* t = GetSegmentAtRow(iNoteRow, SegType); \
221 return To##SegName(t); \
223 Seg* Get##Seg##AtRow(int iNoteRow) \
225 return const_cast<Seg*>( \
226 ((const TimingData*)this)->Get##Seg##AtRow(iNoteRow)); \
228 const Seg* Get##Seg##AtBeat(float fBeat) const \
230 return Get##Seg##AtRow(BeatToNoteRow(fBeat)); \
232 Seg* Get##Seg##AtBeat(float fBeat) \
234 return const_cast<Seg*>( \
235 ((const TimingData*)this)->Get##Seg##AtBeat(fBeat)); \
237 void AddSegment(const Seg& seg) { AddSegment(&seg); }
243#define DefineSegment(Seg, SegType) \
244 DefineSegmentWithName(Seg##Segment, Seg, SEGMENT_##SegType)
246 DefineSegment(BPM, BPM);
247 DefineSegment(Stop, STOP);
248 DefineSegment(Delay, DELAY);
249 DefineSegment(Warp, WARP);
250 DefineSegment(Label, LABEL);
251 DefineSegment(Tickcount, TICKCOUNT);
252 DefineSegment(Combo, COMBO);
253 DefineSegment(Speed, SPEED);
254 DefineSegment(Scroll, SCROLL);
255 DefineSegment(Fake, FAKE);
256 DefineSegment(TimeSignature, TIME_SIG);
258#undef DefineSegmentWithName
262 [[nodiscard]]
auto GetBPMAtRow(
int iNoteRow)
const ->
float
264 return GetBPMSegmentAtRow(iNoteRow)->GetBPM();
267 [[nodiscard]]
auto GetBPMAtBeat(
float fBeat)
const ->
float
269 return GetBPMAtRow(BeatToNoteRow(fBeat));
271 void SetBPMAtRow(
int iNoteRow,
float fBPM)
275 void SetBPMAtBeat(
float fBeat,
float fBPM)
277 SetBPMAtRow(BeatToNoteRow(fBeat), fBPM);
280 [[nodiscard]]
auto GetStopAtRow(
int iNoteRow)
const ->
float
282 return GetStopSegmentAtRow(iNoteRow)->GetPause();
285 [[nodiscard]]
auto GetStopAtBeat(
float fBeat)
const ->
float
287 return GetStopAtRow(BeatToNoteRow(fBeat));
289 void SetStopAtRow(
int iNoteRow,
float fSeconds)
293 void SetStopAtBeat(
float fBeat,
float fSeconds)
295 SetStopAtRow(BeatToNoteRow(fBeat), fSeconds);
298 [[nodiscard]]
auto GetDelayAtRow(
int iNoteRow)
const ->
float
300 return GetDelaySegmentAtRow(iNoteRow)->GetPause();
303 [[nodiscard]]
auto GetDelayAtBeat(
float fBeat)
const ->
float
305 return GetDelayAtRow(BeatToNoteRow(fBeat));
307 void SetDelayAtRow(
int iNoteRow,
float fSeconds)
311 void SetDelayAtBeat(
float fBeat,
float fSeconds)
313 SetDelayAtRow(BeatToNoteRow(fBeat), fSeconds);
316 void SetTimeSignatureAtRow(
int iNoteRow,
int iNum,
int iDen)
321 void SetTimeSignatureAtBeat(
float fBeat,
int iNum,
int iDen)
323 SetTimeSignatureAtRow(BeatToNoteRow(fBeat), iNum, iDen);
326 [[nodiscard]]
auto GetWarpAtRow(
int iNoteRow)
const ->
float
328 return GetWarpSegmentAtRow(iNoteRow)->GetLength();
331 [[nodiscard]]
auto GetWarpAtBeat(
float fBeat)
const ->
float
333 return GetWarpAtRow(BeatToNoteRow(fBeat));
336 void SetWarpAtRow(
int iRow,
float fLength)
340 void SetWarpAtBeat(
float fBeat,
float fLength)
342 AddSegment(
WarpSegment(BeatToNoteRow(fBeat), fLength));
345 [[nodiscard]]
auto GetTickcountAtRow(
int iNoteRow)
const ->
int
347 return GetTickcountSegmentAtRow(iNoteRow)->GetTicks();
350 [[nodiscard]]
auto GetTickcountAtBeat(
float fBeat)
const ->
int
352 return GetTickcountAtRow(BeatToNoteRow(fBeat));
354 void SetTickcountAtRow(
int iNoteRow,
int iTicks)
358 void SetTickcountAtBeat(
float fBeat,
int iTicks)
360 SetTickcountAtRow(BeatToNoteRow(fBeat), iTicks);
363 [[nodiscard]]
auto GetComboAtRow(
int iNoteRow)
const ->
int
365 return GetComboSegmentAtRow(iNoteRow)->GetCombo();
368 [[nodiscard]]
auto GetComboAtBeat(
float fBeat)
const ->
int
370 return GetComboAtRow(BeatToNoteRow(fBeat));
373 [[nodiscard]]
auto GetMissComboAtRow(
int iNoteRow)
const ->
int
375 return GetComboSegmentAtRow(iNoteRow)->GetMissCombo();
378 [[nodiscard]]
auto GetMissComboAtBeat(
float fBeat)
const ->
int
380 return GetMissComboAtRow(BeatToNoteRow(fBeat));
383 [[nodiscard]]
auto GetLabelAtRow(
int iNoteRow)
const ->
const std::string&
385 return GetLabelSegmentAtRow(iNoteRow)->GetLabel();
388 [[nodiscard]]
auto GetLabelAtBeat(
float fBeat)
const ->
const std::string&
390 return GetLabelAtRow(BeatToNoteRow(fBeat));
392 void SetLabelAtRow(
int iNoteRow,
const std::string& sLabel)
396 void SetLabelAtBeat(
float fBeat,
const std::string& sLabel)
398 SetLabelAtRow(BeatToNoteRow(fBeat), sLabel);
401 [[nodiscard]]
auto DoesLabelExist(
const std::string& sLabel)
const -> bool;
403 [[nodiscard]]
auto GetSpeedPercentAtRow(
int iNoteRow)
const ->
float
405 return GetSpeedSegmentAtRow(iNoteRow)->GetRatio();
408 [[nodiscard]]
auto GetSpeedPercentAtBeat(
float fBeat)
const ->
float
410 return GetSpeedPercentAtRow(BeatToNoteRow(fBeat));
413 [[nodiscard]]
auto GetSpeedWaitAtRow(
int iNoteRow)
const ->
float
415 return GetSpeedSegmentAtRow(iNoteRow)->GetDelay();
418 [[nodiscard]]
auto GetSpeedWaitAtBeat(
float fBeat)
const ->
float
420 return GetSpeedWaitAtRow(BeatToNoteRow(fBeat));
424 [[nodiscard]]
auto GetSpeedModeAtRow(
int iNoteRow)
const
427 return GetSpeedSegmentAtRow(iNoteRow)->GetUnit();
430 [[nodiscard]]
auto GetSpeedModeAtBeat(
float fBeat)
const
433 return GetSpeedModeAtRow(BeatToNoteRow(fBeat));
436 void SetSpeedAtRow(
int iNoteRow,
441 AddSegment(
SpeedSegment(iNoteRow, fPercent, fWait, unit));
444 void SetSpeedAtBeat(
float fBeat,
449 SetSpeedAtRow(BeatToNoteRow(fBeat), fPercent, fWait, unit);
452 void SetSpeedPercentAtRow(
int iNoteRow,
float fPercent)
454 const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
455 SetSpeedAtRow(iNoteRow, fPercent, seg->GetDelay(), seg->GetUnit());
458 void SetSpeedWaitAtRow(
int iNoteRow,
float fWait)
460 const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
461 SetSpeedAtRow(iNoteRow, seg->GetRatio(), fWait, seg->GetUnit());
466 const SpeedSegment* seg = GetSpeedSegmentAtRow(iNoteRow);
467 SetSpeedAtRow(iNoteRow, seg->GetRatio(), seg->GetDelay(), unit);
470 void SetSpeedPercentAtBeat(
float fBeat,
float fPercent)
472 SetSpeedPercentAtRow(BeatToNoteRow(fBeat), fPercent);
474 void SetSpeedWaitAtBeat(
float fBeat,
float fWait)
476 SetSpeedWaitAtRow(BeatToNoteRow(fBeat), fWait);
480 SetSpeedModeAtRow(BeatToNoteRow(fBeat), unit);
483 [[nodiscard]]
auto GetDisplayedSpeedPercent(
float fBeat,
484 float fMusicSeconds)
const
487 [[nodiscard]]
auto GetScrollAtRow(
int iNoteRow)
const ->
float
489 return GetScrollSegmentAtRow(iNoteRow)->GetRatio();
492 [[nodiscard]]
auto GetScrollAtBeat(
float fBeat)
const ->
float
494 return GetScrollAtRow(BeatToNoteRow(fBeat));
497 void SetScrollAtRow(
int iNoteRow,
float fPercent)
501 void SetScrollAtBeat(
float fBeat,
float fPercent)
503 SetScrollAtRow(BeatToNoteRow(fBeat), fPercent);
506 [[nodiscard]]
auto GetFakeAtRow(
int iRow)
const ->
float
508 return GetFakeSegmentAtRow(iRow)->GetLength();
511 [[nodiscard]]
auto GetFakeAtBeat(
float fBeat)
const ->
float
513 return GetFakeAtRow(BeatToNoteRow(fBeat));
516 [[nodiscard]]
auto IsWarpAtRow(
int iRow)
const -> bool;
518 [[nodiscard]]
auto IsWarpAtBeat(
float fBeat)
const ->
bool
520 return IsWarpAtRow(BeatToNoteRow(fBeat));
523 [[nodiscard]]
auto IsFakeAtRow(
int iRow)
const -> bool;
525 [[nodiscard]]
auto IsFakeAtBeat(
float fBeat)
const ->
bool
527 return IsFakeAtRow(BeatToNoteRow(fBeat));
536 return !IsWarpAtRow(row) && !IsFakeAtRow(row);
539 [[nodiscard]]
auto IsJudgableAtBeat(
float beat)
const ->
bool
544 void MultiplyBPMInBeatRange(
int iStartIndex,
int iEndIndex,
float fFactor);
546 void NoteRowToMeasureAndBeat(
int iNoteRow,
547 int& iMeasureIndexOut,
549 int& iRowsRemainder)
const;
551 void GetBeatInternal(GetBeatStarts& start,
553 unsigned int max_segment)
const;
554 auto GetElapsedTimeInternal(GetBeatStarts& start,
556 unsigned int max_segment)
const -> float;
557 void GetBeatAndBPSFromElapsedTime(GetBeatArgs& args)
const;
559 [[nodiscard]]
auto GetBeatFromElapsedTime(
float elapsed_time)
const
563 args.elapsed_time = elapsed_time;
564 GetBeatAndBPSFromElapsedTime(args);
568 [[nodiscard]]
auto GetElapsedTimeFromBeat(
float fBeat)
const -> float;
570 void GetBeatAndBPSFromElapsedTimeNoOffset(GetBeatArgs& args)
const;
572 [[nodiscard]]
auto GetBeatFromElapsedTimeNoOffset(
float elapsed_time)
const
576 args.elapsed_time = elapsed_time;
577 GetBeatAndBPSFromElapsedTimeNoOffset(args);
581 [[nodiscard]]
auto GetElapsedTimeFromBeatNoOffset(
float fBeat)
const
583 [[nodiscard]]
auto GetDisplayedBeat(
float fBeat)
const -> float;
585 [[nodiscard]]
auto HasBpmChanges() const ->
bool
587 return GetTimingSegments(SEGMENT_BPM).size() > 1;
590 [[nodiscard]]
auto HasStops() const ->
bool
592 return !GetTimingSegments(SEGMENT_STOP).empty();
594 [[nodiscard]]
auto HasDelays() const ->
bool
596 return !GetTimingSegments(SEGMENT_DELAY).empty();
598 [[nodiscard]]
auto HasWarps() const ->
bool
600 return !GetTimingSegments(SEGMENT_WARP).empty();
602 [[nodiscard]]
auto HasFakes() const ->
bool
604 return !GetTimingSegments(SEGMENT_FAKE).empty();
607 [[nodiscard]]
auto HasSpeedChanges() const ->
bool;
608 [[nodiscard]] auto HasScrollChanges() const ->
bool;
617 FOREACH_ENUM(TimingSegmentType, tst)
619 const auto& us = m_avpTimingSegments[tst];
620 const auto& them = other.m_avpTimingSegments[tst];
623 if (us.size() != them.size()) {
627 for (
unsigned i = 0; i < us.size(); ++i) {
631 if (!(*us[i]).TimingSegment::operator==(*them[i])) {
634 if (!(*us[i]).
operator==(*them[i])) {
654 void ScaleRegion(
float fScale = 1,
656 int iEndRow = MAX_NOTE_ROW,
657 bool bAdjustBPM =
false);
658 void InsertRows(
int iStartRow,
int iRowsToAdd);
659 void DeleteRows(
int iStartRow,
int iRowsToDelete);
661 void SortSegments(TimingSegmentType tst);
663 [[nodiscard]]
auto GetTimingSegments(TimingSegmentType tst)
const
664 ->
const std::vector<TimingSegment*>&
666 return const_cast<TimingData*
>(
this)->GetTimingSegments(tst);
668 auto GetTimingSegments(TimingSegmentType tst)
669 -> std::vector<TimingSegment*>&
671 return m_avpTimingSegments[tst];
683 void PushSelf(lua_State* L);
696 [[nodiscard]]
auto ToVectorString(TimingSegmentType tst,
int dec = 6) const
697 -> std::vector<std::
string>;
709 std::vector<
float> ElapsedTimesAtAllRows;
710 std::vector<
float> ElapsedTimesAtNonEmptyRows;
711 auto BuildAndGetEtaner(const std::vector<
int>& nerv)
712 -> const std::vector<
float>&;
713 auto BuildAndGetEtar(
int lastrow) -> const std::vector<
float>&;
714 void SetElapsedTimesAtAllRows(std::vector<
float>& etar)
716 ElapsedTimesAtAllRows = etar;
719 [[nodiscard]]
auto GetElapsedTimesAtAllRows() const -> std::vector<
float>
721 return ElapsedTimesAtAllRows;
723 void UnsetElapsedTimesAtAllRows()
725 ElapsedTimesAtAllRows.clear();
726 ElapsedTimesAtAllRows.shrink_to_fit();
730 ElapsedTimesAtNonEmptyRows.clear();
731 ElapsedTimesAtNonEmptyRows.shrink_to_fit();
734 [[nodiscard]]
auto WhereUAtBro(
float beat)
const -> float;
735 auto WhereUAtBro(
float beat) -> float;
736 [[nodiscard]]
auto WhereUAtBroNoOffset(
float beat)
const -> float;
737 auto WhereUAtBroNoOffset(
float beat) -> float;
738 auto WhereUAtBro(
int row) -> float;
740 auto ConvertReplayNoteRowsToTimestamps(
const std::vector<int>& nrv,
741 float rate) -> std::vector<float>;
748 std::vector<TimingSegment*> m_avpTimingSegments[NUM_TimingSegmentType];