From cb4b884f892d625f29141cf69f95c12fedb7ff8b Mon Sep 17 00:00:00 2001 From: Zachary Hall Date: Sun, 14 Apr 2024 13:25:49 -0700 Subject: [PATCH] Add struct for playback streams. --- assets/app.dbus.xml | 2 +- assets/dbus_stub_adaptor.hpp | 2 +- assets/dbus_stub_proxy.hpp | 4 ++-- backends/ui/gtk/main_window.cpp | 5 ++--- backends/ui/imgui/main.cpp | 9 +++++---- backends/ui/imgui/main.h | 2 +- dbus.cpp | 23 +++++++++++++++++++---- dbus.hpp | 4 ++-- playback.cpp | 32 +++++++++++++++++++++++--------- playback.h | 13 +++++++++---- 10 files changed, 65 insertions(+), 31 deletions(-) diff --git a/assets/app.dbus.xml b/assets/app.dbus.xml index b282397..e0a2272 100644 --- a/assets/app.dbus.xml +++ b/assets/app.dbus.xml @@ -38,7 +38,7 @@ - + diff --git a/assets/dbus_stub_adaptor.hpp b/assets/dbus_stub_adaptor.hpp index 37a5b2f..215fc0a 100644 --- a/assets/dbus_stub_adaptor.hpp +++ b/assets/dbus_stub_adaptor.hpp @@ -152,7 +152,7 @@ private: virtual void Quit() = 0; virtual void Stop() = 0; virtual void TogglePause() = 0; - virtual std::vector GetStreams() = 0; + virtual std::vector> GetStreams() = 0; virtual void PlayStream(const uint32_t& idx) = 0; private: diff --git a/assets/dbus_stub_proxy.hpp b/assets/dbus_stub_proxy.hpp index 4b7bea8..d9c9bb8 100644 --- a/assets/dbus_stub_proxy.hpp +++ b/assets/dbus_stub_proxy.hpp @@ -136,9 +136,9 @@ public: proxy_->callMethod("TogglePause").onInterface(INTERFACE_NAME); } - std::vector GetStreams() + std::vector> GetStreams() { - std::vector result; + std::vector> result; proxy_->callMethod("GetStreams").onInterface(INTERFACE_NAME).storeResultsTo(result); return result; } diff --git a/backends/ui/gtk/main_window.cpp b/backends/ui/gtk/main_window.cpp index 3bcbf83..4952c34 100644 --- a/backends/ui/gtk/main_window.cpp +++ b/backends/ui/gtk/main_window.cpp @@ -40,14 +40,13 @@ void MainWindow::update_file(optional new_file) { length_label.set_text("00:00"); seek_bar.set_value(0.0); } - int i = 0; for (auto row : stream_selection_box.get_children()) { row->remove_data(Glib::Quark("id")); } stream_selection_box.remove_all(); for (auto &stream : playback->get_streams()) { - int id = i++; - Glib::ustring name(stream.c_str()); + int id = stream.id; + Glib::ustring name(stream.name.c_str()); Gtk::Label idLabel; idLabel.set_text(Glib::ustring(std::format("{}", id).c_str())); Gtk::Label nameLabel; diff --git a/backends/ui/imgui/main.cpp b/backends/ui/imgui/main.cpp index b8bcf9a..7579782 100644 --- a/backends/ui/imgui/main.cpp +++ b/backends/ui/imgui/main.cpp @@ -168,16 +168,17 @@ void MainLoop::GuiFunction() { ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch); for (int i = 0; i < streams.size(); i++) { auto &stream = streams[i]; - if (stream == "") { + if (stream.name == "" && stream.length == 0) { continue; } - if (stream.starts_with(filter)) { + if (stream.name.starts_with(filter)) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); - ImGui::Text("%i", i); + ImGui::Text("%i", stream.id); ImGui::TableSetColumnIndex(1); const bool is_selected = playback->get_current_stream() == i; - if (ImGui::Selectable(stream.c_str(), is_selected, 0)) { + if (ImGui::Selectable(stream.name.c_str(), is_selected, 0)) { + length = stream.length; playback->play_stream(i); } if (is_selected) { diff --git a/backends/ui/imgui/main.h b/backends/ui/imgui/main.h index eabbc6c..9d90ebd 100644 --- a/backends/ui/imgui/main.h +++ b/backends/ui/imgui/main.h @@ -53,7 +53,7 @@ class MainLoop : public RendererBackend { UIBackend *cur_backend; friend class ImGuiUIBackend; std::atomic_bool exit_flag; - std::vector streams; + std::vector streams; public: Playback *playback; vector args; diff --git a/dbus.cpp b/dbus.cpp index 167f006..1eefa5d 100644 --- a/dbus.cpp +++ b/dbus.cpp @@ -405,8 +405,14 @@ std::vector DBusAPI::GetAllAndClear(const std::string &handle) { uint32_t DBusAPI::StreamIdx() { return playback->get_current_stream(); } -std::vector DBusAPI::GetStreams() { - return playback->get_streams(); +std::vector> DBusAPI::GetStreams() { + std::vector> output; + auto streams = playback->get_streams(); + for (auto stream : streams) { + sdbus::Struct tmp(stream.length, stream.name, stream.id); + output.push_back(tmp); + } + return output; } void DBusAPI::PlayStream(const uint32_t &idx) { playback->play_stream((int)idx); @@ -487,8 +493,17 @@ void DBusAPISender::Load(std::string filePath) { int DBusAPISender::get_current_stream() { return (int)ProxyInterfaces::StreamIdx(); } -std::vector DBusAPISender::get_streams() { - return ProxyInterfaces::GetStreams(); +std::vector DBusAPISender::get_streams() { + std::vector output; + auto input = ProxyInterfaces::GetStreams(); + for (auto stream : input) { + PlaybackStream tmp; + tmp.length = stream.get<0>(); + tmp.name = stream.get<1>(); + tmp.id = stream.get<2>(); + output.push_back(tmp); + } + return output; } bool DBusAPISender::IsPaused() { return ProxyInterfaces::Paused(); diff --git a/dbus.hpp b/dbus.hpp index 9f50f61..99797b8 100644 --- a/dbus.hpp +++ b/dbus.hpp @@ -161,7 +161,7 @@ class DBusAPI : public sdbus::AdaptorInterfaces GetStreams() override; + std::vector> GetStreams() override; void PlayStream(const uint32_t &idx) override; // API @@ -229,7 +229,7 @@ class DBusAPISender : public Playback, public sdbus::ProxyInterfaces get_streams() override; + std::vector get_streams() override; // Constructors and destructors. // The constructor is protected because there is a different API that should be used for creation. protected: diff --git a/playback.cpp b/playback.cpp index 7a7bf9c..fec4572 100644 --- a/playback.cpp +++ b/playback.cpp @@ -183,23 +183,37 @@ VGMSTREAM *PlaybackInstance::LoadVgm(const char *file, int idx) { close_vgmstream(output); stream_list_mutex.lock(); streams.clear(); - streams.push_back("Default"); - for (int i = 1; i <= stream_count; i++) { + PlaybackStream defaultStream; + defaultStream.id = 0; + defaultStream.name = "Default"; + streams.push_back(defaultStream); + for (int i = 0; i <= stream_count; i++) { + PlaybackStream stream; + stream.id = i; + stream.length = 0; + stream.name = ""; if (!sf) { - streams.push_back(""); + streams.push_back(stream); continue; } sf->stream_index = i; auto *tmp = init_vgmstream_from_STREAMFILE(sf); if (!tmp) { - streams.push_back(""); + streams.push_back(stream); continue; } reset_vgmstream(tmp); + + stream.length = (double)tmp->num_samples / (double)tmp->sample_rate; char *buf = (char*)malloc(STREAM_NAME_SIZE + 1); memset(buf, 0, STREAM_NAME_SIZE + 1); strncpy(buf, tmp->stream_name, STREAM_NAME_SIZE); - streams.push_back(buf); + + if (i == 0) { + stream.name = std::format("Default ({})", buf); + } else { + stream.name = buf; + } free(buf); close_vgmstream(tmp); } @@ -222,7 +236,7 @@ VGMSTREAM *PlaybackInstance::LoadVgm(const char *file, int idx) { vgmstream_spec.channels = output->channels; vgmstream_spec.freq = output->sample_rate; - length = (double)output->num_samples / (double)output->sample_rate; + length = streams[idx].length; update.store(true); current_file_mutex.lock(); current_file = std::string(file); @@ -379,7 +393,7 @@ void PlaybackInstance::ThreadFunc() { } if (stream_changed.exchange(false)) { std::string file = current_file.value(); - if (streams[current_stream] == "" || current_stream < 0 || current_stream >= streams.size()) { + if (streams[current_stream].name == "" || streams[current_stream].length <= 0 || current_stream < 0 || current_stream >= streams.size()) { if (stream != nullptr) { current_stream = stream->stream_index; } else { @@ -718,8 +732,8 @@ Playback *Playback::Create(bool *daemon_found, bool daemon) { DEBUG.writeln("Creating new playback instance."); return new PlaybackInstance(); } -std::vector PlaybackInstance::get_streams() { - std::vector output; +std::vector PlaybackInstance::get_streams() { + std::vector output; for (auto stream : streams) { output.push_back(stream); } diff --git a/playback.h b/playback.h index 65eefad..c36013e 100644 --- a/playback.h +++ b/playback.h @@ -46,6 +46,11 @@ enum { /// @brief Playback has started. If @ref PlaybackSignalStopped has also been signalled, call @ref Playback::IsStopped to find out if playback is currently playing. PlaybackSignalStarted = 1 << 9 }; +struct PlaybackStream { + double length; + std::string name; + int id; +}; /// @brief Playback handler base class. class Playback { protected: @@ -83,8 +88,8 @@ class Playback { inline virtual int get_current_stream() { return 0; } - inline virtual std::vector get_streams() { - std::vector output; + inline virtual std::vector get_streams() { + std::vector output; return output; } inline virtual void play_stream(int idx) {} @@ -222,7 +227,7 @@ private: void UnloadMix(Mix_Music* music); void UnloadVgm(VGMSTREAM *stream); VGMSTREAM *stream; - std::vector streams; + std::vector streams; std::mutex stream_list_mutex; double real_volume = 1.0; void ThreadFunc(); @@ -244,7 +249,7 @@ public: inline bool is_proxy() override { return false; } - std::vector get_streams() override; + std::vector get_streams() override; void play_stream(int idx) override; void Load(std::string filePath) override; double GetPosition() override;