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;