diff options
Diffstat (limited to 'src/tangara/audio/stream_cues.cpp')
| -rw-r--r-- | src/tangara/audio/stream_cues.cpp | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/src/tangara/audio/stream_cues.cpp b/src/tangara/audio/stream_cues.cpp new file mode 100644 index 00000000..7a6a1426 --- /dev/null +++ b/src/tangara/audio/stream_cues.cpp @@ -0,0 +1,65 @@ +/* + * Copyright 2024 jacqueline <me@jacqueline.id.au> + * + * SPDX-License-Identifier: GPL-3.0-only + */ + +#include "audio/stream_cues.hpp" + +#include <cstdint> +#include <memory> + +namespace audio { + +StreamCues::StreamCues() : now_(0) {} + +auto StreamCues::update(uint32_t sample) -> void { + if (sample < now_) { + // The current time must have overflowed. Deal with any cues between now_ + // and UINT32_MAX, then proceed as normal. + while (!upcoming_.empty() && upcoming_.front().start_at > now_) { + current_ = upcoming_.front(); + upcoming_.pop_front(); + } + } + now_ = sample; + + while (!upcoming_.empty() && upcoming_.front().start_at <= now_) { + current_ = upcoming_.front(); + upcoming_.pop_front(); + } +} + +auto StreamCues::addCue(std::shared_ptr<TrackInfo> track, uint32_t sample) + -> void { + if (sample == now_) { + current_ = {track, now_}; + } else { + upcoming_.push_back(Cue{ + .track = track, + .start_at = sample, + }); + } +} + +auto StreamCues::current() -> std::pair<std::shared_ptr<TrackInfo>, uint32_t> { + if (!current_) { + return {}; + } + + uint32_t duration; + if (now_ < current_->start_at) { + // now_ overflowed since this track started. + duration = now_ + (UINT32_MAX - current_->start_at); + } else { + duration = now_ - current_->start_at; + } + + return {current_->track, duration}; +} + +auto StreamCues::hasStream() -> bool { + return current_ || !upcoming_.empty(); +} + +} // namespace audio |
