summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorailurux <ailuruxx@gmail.com>2024-02-12 15:36:56 +1100
committerailurux <ailuruxx@gmail.com>2024-02-12 15:36:56 +1100
commit9512bd97bbac48fa33339cc248c76070063bbc61 (patch)
tree00ecbfecf5961954a7f7e349a73ab0ba52e90d88 /src
parent679521d8e37171e8698d618fca9a7908348c429f (diff)
downloadtangara-fw-9512bd97bbac48fa33339cc248c76070063bbc61.tar.gz
Add buttons for shuffle + repeat track
Diffstat (limited to 'src')
-rw-r--r--src/audio/audio_fsm.cpp2
-rw-r--r--src/audio/include/track_queue.hpp14
-rw-r--r--src/audio/track_queue.cpp40
-rw-r--r--src/ui/include/ui_fsm.hpp2
-rw-r--r--src/ui/ui_fsm.cpp39
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);
}