diff options
| author | ailurux <ailuruxx@gmail.com> | 2024-02-12 15:36:56 +1100 |
|---|---|---|
| committer | ailurux <ailuruxx@gmail.com> | 2024-02-12 15:36:56 +1100 |
| commit | 9512bd97bbac48fa33339cc248c76070063bbc61 (patch) | |
| tree | 00ecbfecf5961954a7f7e349a73ab0ba52e90d88 /src | |
| parent | 679521d8e37171e8698d618fca9a7908348c429f (diff) | |
| download | tangara-fw-9512bd97bbac48fa33339cc248c76070063bbc61.tar.gz | |
Add buttons for shuffle + repeat track
Diffstat (limited to 'src')
| -rw-r--r-- | src/audio/audio_fsm.cpp | 2 | ||||
| -rw-r--r-- | src/audio/include/track_queue.hpp | 14 | ||||
| -rw-r--r-- | src/audio/track_queue.cpp | 40 | ||||
| -rw-r--r-- | src/ui/include/ui_fsm.hpp | 2 | ||||
| -rw-r--r-- | src/ui/ui_fsm.cpp | 39 |
5 files changed, 81 insertions, 16 deletions
diff --git a/src/audio/audio_fsm.cpp b/src/audio/audio_fsm.cpp index 54ffa51d..b80e8c30 100644 --- a/src/audio/audio_fsm.cpp +++ b/src/audio/audio_fsm.cpp @@ -320,7 +320,7 @@ void Playback::react(const internal::InputFileClosed& ev) {} void Playback::react(const internal::InputFileFinished& ev) { ESP_LOGI(kTag, "finished playing file"); - sServices->track_queue().next(); + sServices->track_queue().finish(); if (!sServices->track_queue().current()) { transit<Standby>(); } diff --git a/src/audio/include/track_queue.hpp b/src/audio/include/track_queue.hpp index 5b14fd4a..fd6061a7 100644 --- a/src/audio/include/track_queue.hpp +++ b/src/audio/include/track_queue.hpp @@ -33,13 +33,13 @@ class RandomIterator { // Note resizing has the side-effect of restarting iteration. auto resize(size_t) -> void; - auto repeat(bool) -> void; + auto replay(bool) -> void; private: size_t seed_; size_t pos_; size_t size_; - bool repeat_; + bool replay_; }; /* @@ -85,6 +85,12 @@ class TrackQueue { auto next() -> void; auto previous() -> void; + /* + * Called when the current track finishes + */ + auto finish() -> void; + + auto skipTo(database::TrackId) -> void; /* @@ -98,6 +104,9 @@ class TrackQueue { auto repeat(bool) -> void; auto repeat() const -> bool; + auto replay(bool) -> void; + auto replay() const -> bool; + auto serialise() -> std::string; auto deserialise(const std::string&) -> void; @@ -115,6 +124,7 @@ class TrackQueue { std::optional<RandomIterator> shuffle_; bool repeat_; + bool replay_; }; } // namespace audio diff --git a/src/audio/track_queue.cpp b/src/audio/track_queue.cpp index d68f2821..5ac9d1f8 100644 --- a/src/audio/track_queue.cpp +++ b/src/audio/track_queue.cpp @@ -34,12 +34,12 @@ namespace audio { [[maybe_unused]] static constexpr char kTag[] = "tracks"; RandomIterator::RandomIterator(size_t size) - : seed_(), pos_(0), size_(size), repeat_(false) { + : seed_(), pos_(0), size_(size), replay_(false) { esp_fill_random(&seed_, sizeof(seed_)); } auto RandomIterator::current() const -> size_t { - if (pos_ < size_ || repeat_) { + if (pos_ < size_ || replay_) { return MillerShuffle(pos_, seed_, size_); } return size_; @@ -65,8 +65,8 @@ auto RandomIterator::resize(size_t s) -> void { pos_ = 0; } -auto RandomIterator::repeat(bool r) -> void { - repeat_ = r; +auto RandomIterator::replay(bool r) -> void { + replay_ = r; } auto notifyChanged(bool current_changed) -> void { @@ -81,7 +81,8 @@ TrackQueue::TrackQueue(tasks::WorkerPool& bg_worker) pos_(0), tracks_(&memory::kSpiRamResource), shuffle_(), - repeat_(false) {} + repeat_(false), + replay_(false) {} auto TrackQueue::current() const -> std::optional<database::TrackId> { const std::shared_lock<std::shared_mutex> lock(mutex_); @@ -202,7 +203,7 @@ auto TrackQueue::next() -> void { pos_ = shuffle_->current(); } else { if (pos_ + 1 >= tracks_.size()) { - if (repeat_) { + if (replay_) { pos_ = 0; } } else { @@ -231,6 +232,14 @@ auto TrackQueue::previous() -> void { notifyChanged(true); } +auto TrackQueue::finish() -> void { + if (repeat_) { + notifyChanged(true); + } else { + next(); + } +} + auto TrackQueue::skipTo(database::TrackId id) -> void { // Defer this work to the background not because it's particularly // long-running (although it could be), but because we want to ensure we only @@ -279,7 +288,7 @@ auto TrackQueue::random(bool en) -> void { // repeated calls with en == true will re-shuffle. if (en) { shuffle_.emplace(tracks_.size()); - shuffle_->repeat(repeat_); + shuffle_->replay(replay_); } else { shuffle_.reset(); } @@ -298,9 +307,6 @@ auto TrackQueue::repeat(bool en) -> void { { const std::unique_lock<std::shared_mutex> lock(mutex_); repeat_ = en; - if (shuffle_) { - shuffle_->repeat(en); - } } notifyChanged(false); @@ -311,6 +317,20 @@ auto TrackQueue::repeat() const -> bool { return repeat_; } +auto TrackQueue::replay(bool en) -> void { + const std::unique_lock<std::shared_mutex> lock(mutex_); + replay_ = en; + if (shuffle_) { + shuffle_->replay(en); + } + notifyChanged(false); +} + +auto TrackQueue::replay() const -> bool { + const std::shared_lock<std::shared_mutex> lock(mutex_); + return replay_; +} + auto TrackQueue::serialise() -> std::string { cppbor::Array tracks{}; for (database::TrackId track : tracks_) { diff --git a/src/ui/include/ui_fsm.hpp b/src/ui/include/ui_fsm.hpp index c097e764..52ab77a5 100644 --- a/src/ui/include/ui_fsm.hpp +++ b/src/ui/include/ui_fsm.hpp @@ -116,6 +116,7 @@ class UiState : public tinyfsm::Fsm<UiState> { static lua::Property sQueuePosition; static lua::Property sQueueSize; + static lua::Property sQueueReplay; static lua::Property sQueueRepeat; static lua::Property sQueueRandom; @@ -165,6 +166,7 @@ class Lua : public UiState { auto SetPlaying(const lua::LuaValue&) -> bool; auto SetRandom(const lua::LuaValue&) -> bool; auto SetRepeat(const lua::LuaValue&) -> bool; + auto SetReplay(const lua::LuaValue&) -> bool; auto QueueNext(lua_State*) -> int; auto QueuePrevious(lua_State*) -> int; diff --git a/src/ui/ui_fsm.cpp b/src/ui/ui_fsm.cpp index 12584ec7..6e4bbe6f 100644 --- a/src/ui/ui_fsm.cpp +++ b/src/ui/ui_fsm.cpp @@ -127,8 +127,30 @@ lua::Property UiState::sPlaybackPosition{0}; lua::Property UiState::sQueuePosition{0}; lua::Property UiState::sQueueSize{0}; -lua::Property UiState::sQueueRepeat{false}; -lua::Property UiState::sQueueRandom{false}; +lua::Property UiState::sQueueRepeat{false, [](const lua::LuaValue& val) { + if (!std::holds_alternative<bool>(val)) { + return false; + } + bool new_val = std::get<bool>(val); + sServices->track_queue().repeat(new_val); + return true; +}}; +lua::Property UiState::sQueueReplay{false, [](const lua::LuaValue& val) { + if (!std::holds_alternative<bool>(val)) { + return false; + } + bool new_val = std::get<bool>(val); + sServices->track_queue().replay(new_val); + return true; +}}; +lua::Property UiState::sQueueRandom{false, [](const lua::LuaValue& val) { + if (!std::holds_alternative<bool>(val)) { + return false; + } + bool new_val = std::get<bool>(val); + sServices->track_queue().random(new_val); + return true; +}}; lua::Property UiState::sVolumeCurrentPct{ 0, [](const lua::LuaValue& val) { @@ -296,6 +318,7 @@ void UiState::react(const audio::QueueUpdate&) { sQueuePosition.Update(current_pos); sQueueRandom.Update(queue.random()); sQueueRepeat.Update(queue.repeat()); + sQueueReplay.Update(queue.replay()); } void UiState::react(const audio::PlaybackStarted& ev) { @@ -417,7 +440,8 @@ void Lua::entry() { {"previous", [&](lua_State* s) { return QueuePrevious(s); }}, {"position", &sQueuePosition}, {"size", &sQueueSize}, - {"replay", &sQueueRepeat}, + {"replay", &sQueueReplay}, + {"repeat_track", &sQueueRepeat}, {"random", &sQueueRandom}, }); sLua->bridge().AddPropertyModule("volume", @@ -564,6 +588,15 @@ auto Lua::SetRepeat(const lua::LuaValue& val) -> bool { return true; } +auto Lua::SetReplay(const lua::LuaValue& val) -> bool { + if (!std::holds_alternative<bool>(val)) { + return false; + } + bool b = std::get<bool>(val); + sServices->track_queue().replay(b); + return true; +} + void Lua::exit() { lv_group_set_default(NULL); } |
