From c479d699d059bc58e6850d43b14f2e91c2076e12 Mon Sep 17 00:00:00 2001 From: ailurux Date: Tue, 17 Sep 2024 14:13:05 +1000 Subject: [PATCH] Implements seeking to saved position for tracks --- lua/browser.lua | 4 +++- src/tangara/audio/audio_events.hpp | 2 ++ src/tangara/audio/audio_fsm.cpp | 2 +- src/tangara/audio/track_queue.cpp | 23 ++++++++++++++++++++++- src/tangara/audio/track_queue.hpp | 1 + src/tangara/lua/lua_queue.cpp | 14 ++++++++++++++ 6 files changed, 43 insertions(+), 3 deletions(-) diff --git a/lua/browser.lua b/lua/browser.lua index 731c1dc6..3d7e3e9d 100644 --- a/lua/browser.lua +++ b/lua/browser.lua @@ -105,8 +105,10 @@ return screen:new{ local track = database.track_by_id(contents) if (track) then print("Track saved position: ", track.saved_position) + queue.play_from(track.filepath, track.saved_position) + else + queue.add(contents) end - queue.add(contents) playback.playing:set(true) backstack.push(playing:new()) end diff --git a/src/tangara/audio/audio_events.hpp b/src/tangara/audio/audio_events.hpp index 56d150b2..89dc28ff 100644 --- a/src/tangara/audio/audio_events.hpp +++ b/src/tangara/audio/audio_events.hpp @@ -106,6 +106,8 @@ struct QueueUpdate : tinyfsm::Event { kBulkLoadingUpdate, }; Reason reason; + + std::optional seek_to_second; }; struct StepUpVolume : tinyfsm::Event {}; diff --git a/src/tangara/audio/audio_fsm.cpp b/src/tangara/audio/audio_fsm.cpp index 71decd48..dd9f2fde 100644 --- a/src/tangara/audio/audio_fsm.cpp +++ b/src/tangara/audio/audio_fsm.cpp @@ -113,7 +113,7 @@ auto AudioState::emitPlaybackUpdate(bool paused) -> void { void AudioState::react(const QueueUpdate& ev) { SetTrack cmd{ .new_track = std::monostate{}, - .seek_to_second = {}, + .seek_to_second = ev.seek_to_second, }; auto current = sServices->track_queue().current(); diff --git a/src/tangara/audio/track_queue.cpp b/src/tangara/audio/track_queue.cpp index 2c1faf96..ff24637b 100644 --- a/src/tangara/audio/track_queue.cpp +++ b/src/tangara/audio/track_queue.cpp @@ -85,6 +85,16 @@ auto notifyChanged(bool current_changed, Reason reason) -> void { events::Audio().Dispatch(ev); } +auto notifyPlayFrom(uint32_t start_from_position) -> void { + QueueUpdate ev{ + .current_changed = true, + .reason = Reason::kExplicitUpdate, + .seek_to_second = start_from_position, + }; + events::Ui().Dispatch(ev); + events::Audio().Dispatch(ev); +} + TrackQueue::TrackQueue(tasks::WorkerPool& bg_worker, database::Handle db) : mutex_(), bg_worker_(bg_worker), @@ -109,6 +119,17 @@ auto TrackQueue::current() const -> TrackItem { return val; } +auto TrackQueue::playFromPosition(const std::string& filepath, + uint32_t position) -> void { + clear(); + { + const std::unique_lock lock(mutex_); + playlist_.append(filepath); + updateShuffler(true); + } + notifyPlayFrom(position); +} + auto TrackQueue::currentPosition() const -> size_t { const std::shared_lock lock(mutex_); return position_; @@ -245,7 +266,7 @@ auto TrackQueue::currentPosition(size_t position) -> bool { goTo(position); } - // If we're explicitly setting the position, we want to treat it as though + // If we're explicitly setting the position, we want to treat it as though // the current track has changed, even if the position was the same notifyChanged(true, Reason::kExplicitUpdate); return true; diff --git a/src/tangara/audio/track_queue.hpp b/src/tangara/audio/track_queue.hpp index a8d1dc3a..727b4be0 100644 --- a/src/tangara/audio/track_queue.hpp +++ b/src/tangara/audio/track_queue.hpp @@ -78,6 +78,7 @@ class TrackQueue { auto open() -> bool; auto openPlaylist(const std::string& playlist_file, bool notify = true) -> bool; + auto playFromPosition(const std::string& filepath, uint32_t position) -> void; using Item = std::variant; diff --git a/src/tangara/lua/lua_queue.cpp b/src/tangara/lua/lua_queue.cpp index 7eb32c62..07093390 100644 --- a/src/tangara/lua/lua_queue.cpp +++ b/src/tangara/lua/lua_queue.cpp @@ -79,10 +79,24 @@ static auto queue_open_playlist(lua_State* state) -> int { return 0; } +static auto queue_play_from(lua_State* state) -> int { + Bridge* instance = Bridge::Get(state); + audio::TrackQueue& queue = instance->services().track_queue(); + size_t len = 0; + const char* str = luaL_checklstring(state, 1, &len); + if (!str) { + return 0; + } + auto pos = luaL_checkinteger(state, 2); + queue.playFromPosition(str, pos); + return 0; +} + static const struct luaL_Reg kQueueFuncs[] = { {"add", queue_add}, {"clear", queue_clear}, {"open_playlist", queue_open_playlist}, + {"play_from", queue_play_from}, {NULL, NULL}}; static auto lua_queue(lua_State* state) -> int {