#include "TrackLockProxy.h" #include "Track.h" using namespace std; using namespace track; //-------------------------------------------------------------- /* Constructor */ TrackLockProxy::TrackLockProxy(std::mutex &mtx, const Track *track) : m_lock(mtx) , m_track(track) { m_notes = m_track->m_notes; } //-------------------------------------------------------------- /* Access a note by index */ const Note &TrackLockProxy::operator[](const size_t index) const { return m_notes[index]; } //-------------------------------------------------------------- /* Get the active notes at a specific time with a lookahead window */ ActiveNotes TrackLockProxy::getActiveNotesAt(const Seconds currentTime, const Seconds lookaheadWindow) const { ActiveNotes result; getActiveNotesAt(currentTime, lookaheadWindow, result); return result; } //-------------------------------------------------------------- /* Get the active notes at a specific time with a lookahead window */ void TrackLockProxy::getActiveNotesAt(const Seconds currentTime, const Seconds lookaheadWindow, ActiveNotes &outNotes) const { // Clear the output buffers before filling them with active notes // without releasing the allocated memory outNotes.playing.clear(); // Clear the currently playing notes buffer outNotes.upcoming.clear(); // Clear the upcoming notes buffer const Seconds lookaheadEnd = currentTime + lookaheadWindow; for (const auto ¬e : m_notes) { // Extract the notes that are currently playing if (note.startTime <= currentTime && note.endTime > currentTime) outNotes.playing.push_back(note); // Extract the notes that are upcoming in the lookahead window if (note.startTime <= lookaheadEnd && note.endTime >= currentTime) outNotes.upcoming.push_back(note); // Early exit: Notes are sorted by startTime, so if we reach a note // that starts after the lookahead window, we can stop searching if (note.startTime > lookaheadEnd) break; } } //-------------------------------------------------------------- /* Get the duration of the track */ Seconds TrackLockProxy::getDuration() const { if (empty()) return Seconds(0); return m_notes.back().endTime; } //-------------------------------------------------------------- /* Get the span of notes */ NotesView TrackLockProxy::get() const noexcept { return m_notes; } //-------------------------------------------------------------- /* Get the first iterator of the notes */ auto TrackLockProxy::begin() const noexcept { return m_notes.begin(); } //-------------------------------------------------------------- /* Get the end iterator of the notes */ auto TrackLockProxy::end() const noexcept { return m_notes.end(); } //-------------------------------------------------------------- /* Check if the notes span is empty */ bool TrackLockProxy::empty() const noexcept { return m_notes.empty(); } //-------------------------------------------------------------- /* Get the size of the notes span */ size_t TrackLockProxy::size() const noexcept { return m_notes.size(); } //--------------------------------------------------------------