Add struct for playback streams.
This commit is contained in:
parent
7ff0d40da3
commit
cb4b884f89
10 changed files with 65 additions and 31 deletions
|
@ -38,7 +38,7 @@
|
||||||
<method name="Stop" />
|
<method name="Stop" />
|
||||||
<method name="TogglePause" />
|
<method name="TogglePause" />
|
||||||
<method name="GetStreams">
|
<method name="GetStreams">
|
||||||
<arg name="streams" type="as" direction="out" />
|
<arg name="streams" type="a(dsi)" direction="out" />
|
||||||
</method>
|
</method>
|
||||||
<method name="PlayStream">
|
<method name="PlayStream">
|
||||||
<arg name="idx" type="u" direction="in" />
|
<arg name="idx" type="u" direction="in" />
|
||||||
|
|
|
@ -152,7 +152,7 @@ private:
|
||||||
virtual void Quit() = 0;
|
virtual void Quit() = 0;
|
||||||
virtual void Stop() = 0;
|
virtual void Stop() = 0;
|
||||||
virtual void TogglePause() = 0;
|
virtual void TogglePause() = 0;
|
||||||
virtual std::vector<std::string> GetStreams() = 0;
|
virtual std::vector<sdbus::Struct<double, std::string, int32_t>> GetStreams() = 0;
|
||||||
virtual void PlayStream(const uint32_t& idx) = 0;
|
virtual void PlayStream(const uint32_t& idx) = 0;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -136,9 +136,9 @@ public:
|
||||||
proxy_->callMethod("TogglePause").onInterface(INTERFACE_NAME);
|
proxy_->callMethod("TogglePause").onInterface(INTERFACE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetStreams()
|
std::vector<sdbus::Struct<double, std::string, int32_t>> GetStreams()
|
||||||
{
|
{
|
||||||
std::vector<std::string> result;
|
std::vector<sdbus::Struct<double, std::string, int32_t>> result;
|
||||||
proxy_->callMethod("GetStreams").onInterface(INTERFACE_NAME).storeResultsTo(result);
|
proxy_->callMethod("GetStreams").onInterface(INTERFACE_NAME).storeResultsTo(result);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,14 +40,13 @@ void MainWindow::update_file(optional<std::string> new_file) {
|
||||||
length_label.set_text("00:00");
|
length_label.set_text("00:00");
|
||||||
seek_bar.set_value(0.0);
|
seek_bar.set_value(0.0);
|
||||||
}
|
}
|
||||||
int i = 0;
|
|
||||||
for (auto row : stream_selection_box.get_children()) {
|
for (auto row : stream_selection_box.get_children()) {
|
||||||
row->remove_data(Glib::Quark("id"));
|
row->remove_data(Glib::Quark("id"));
|
||||||
}
|
}
|
||||||
stream_selection_box.remove_all();
|
stream_selection_box.remove_all();
|
||||||
for (auto &stream : playback->get_streams()) {
|
for (auto &stream : playback->get_streams()) {
|
||||||
int id = i++;
|
int id = stream.id;
|
||||||
Glib::ustring name(stream.c_str());
|
Glib::ustring name(stream.name.c_str());
|
||||||
Gtk::Label idLabel;
|
Gtk::Label idLabel;
|
||||||
idLabel.set_text(Glib::ustring(std::format("{}", id).c_str()));
|
idLabel.set_text(Glib::ustring(std::format("{}", id).c_str()));
|
||||||
Gtk::Label nameLabel;
|
Gtk::Label nameLabel;
|
||||||
|
|
|
@ -168,16 +168,17 @@ void MainLoop::GuiFunction() {
|
||||||
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
ImGui::TableSetupColumn("Name", ImGuiTableColumnFlags_WidthStretch);
|
||||||
for (int i = 0; i < streams.size(); i++) {
|
for (int i = 0; i < streams.size(); i++) {
|
||||||
auto &stream = streams[i];
|
auto &stream = streams[i];
|
||||||
if (stream == "") {
|
if (stream.name == "" && stream.length == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (stream.starts_with(filter)) {
|
if (stream.name.starts_with(filter)) {
|
||||||
ImGui::TableNextRow();
|
ImGui::TableNextRow();
|
||||||
ImGui::TableSetColumnIndex(0);
|
ImGui::TableSetColumnIndex(0);
|
||||||
ImGui::Text("%i", i);
|
ImGui::Text("%i", stream.id);
|
||||||
ImGui::TableSetColumnIndex(1);
|
ImGui::TableSetColumnIndex(1);
|
||||||
const bool is_selected = playback->get_current_stream() == i;
|
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);
|
playback->play_stream(i);
|
||||||
}
|
}
|
||||||
if (is_selected) {
|
if (is_selected) {
|
||||||
|
|
|
@ -53,7 +53,7 @@ class MainLoop : public RendererBackend {
|
||||||
UIBackend *cur_backend;
|
UIBackend *cur_backend;
|
||||||
friend class ImGuiUIBackend;
|
friend class ImGuiUIBackend;
|
||||||
std::atomic_bool exit_flag;
|
std::atomic_bool exit_flag;
|
||||||
std::vector<std::string> streams;
|
std::vector<PlaybackStream> streams;
|
||||||
public:
|
public:
|
||||||
Playback *playback;
|
Playback *playback;
|
||||||
vector<std::string> args;
|
vector<std::string> args;
|
||||||
|
|
23
dbus.cpp
23
dbus.cpp
|
@ -405,8 +405,14 @@ std::vector<std::string> DBusAPI::GetAllAndClear(const std::string &handle) {
|
||||||
uint32_t DBusAPI::StreamIdx() {
|
uint32_t DBusAPI::StreamIdx() {
|
||||||
return playback->get_current_stream();
|
return playback->get_current_stream();
|
||||||
}
|
}
|
||||||
std::vector<std::string> DBusAPI::GetStreams() {
|
std::vector<sdbus::Struct<double, std::string, int32_t>> DBusAPI::GetStreams() {
|
||||||
return playback->get_streams();
|
std::vector<sdbus::Struct<double, std::string, int32_t>> output;
|
||||||
|
auto streams = playback->get_streams();
|
||||||
|
for (auto stream : streams) {
|
||||||
|
sdbus::Struct<double, std::string, int32_t> tmp(stream.length, stream.name, stream.id);
|
||||||
|
output.push_back(tmp);
|
||||||
|
}
|
||||||
|
return output;
|
||||||
}
|
}
|
||||||
void DBusAPI::PlayStream(const uint32_t &idx) {
|
void DBusAPI::PlayStream(const uint32_t &idx) {
|
||||||
playback->play_stream((int)idx);
|
playback->play_stream((int)idx);
|
||||||
|
@ -487,8 +493,17 @@ void DBusAPISender::Load(std::string filePath) {
|
||||||
int DBusAPISender::get_current_stream() {
|
int DBusAPISender::get_current_stream() {
|
||||||
return (int)ProxyInterfaces::StreamIdx();
|
return (int)ProxyInterfaces::StreamIdx();
|
||||||
}
|
}
|
||||||
std::vector<std::string> DBusAPISender::get_streams() {
|
std::vector<PlaybackStream> DBusAPISender::get_streams() {
|
||||||
return ProxyInterfaces::GetStreams();
|
std::vector<PlaybackStream> 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() {
|
bool DBusAPISender::IsPaused() {
|
||||||
return ProxyInterfaces::Paused();
|
return ProxyInterfaces::Paused();
|
||||||
|
|
4
dbus.hpp
4
dbus.hpp
|
@ -161,7 +161,7 @@ class DBusAPI : public sdbus::AdaptorInterfaces<com::complecwaft::Looper_adaptor
|
||||||
bool IsDaemon() override;
|
bool IsDaemon() override;
|
||||||
void Quit() override;
|
void Quit() override;
|
||||||
uint32_t StreamIdx() override;
|
uint32_t StreamIdx() override;
|
||||||
std::vector<std::string> GetStreams() override;
|
std::vector<sdbus::Struct<double, std::string, int32_t>> GetStreams() override;
|
||||||
void PlayStream(const uint32_t &idx) override;
|
void PlayStream(const uint32_t &idx) override;
|
||||||
|
|
||||||
// API
|
// API
|
||||||
|
@ -229,7 +229,7 @@ class DBusAPISender : public Playback, public sdbus::ProxyInterfaces<com::comple
|
||||||
float GetVolume() override;
|
float GetVolume() override;
|
||||||
int get_current_stream() override;
|
int get_current_stream() override;
|
||||||
void Load(std::string filePath) override;
|
void Load(std::string filePath) override;
|
||||||
std::vector<std::string> get_streams() override;
|
std::vector<PlaybackStream> get_streams() override;
|
||||||
// Constructors and destructors.
|
// Constructors and destructors.
|
||||||
// The constructor is protected because there is a different API that should be used for creation.
|
// The constructor is protected because there is a different API that should be used for creation.
|
||||||
protected:
|
protected:
|
||||||
|
|
32
playback.cpp
32
playback.cpp
|
@ -183,23 +183,37 @@ VGMSTREAM *PlaybackInstance::LoadVgm(const char *file, int idx) {
|
||||||
close_vgmstream(output);
|
close_vgmstream(output);
|
||||||
stream_list_mutex.lock();
|
stream_list_mutex.lock();
|
||||||
streams.clear();
|
streams.clear();
|
||||||
streams.push_back("Default");
|
PlaybackStream defaultStream;
|
||||||
for (int i = 1; i <= stream_count; i++) {
|
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) {
|
if (!sf) {
|
||||||
streams.push_back("");
|
streams.push_back(stream);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
sf->stream_index = i;
|
sf->stream_index = i;
|
||||||
auto *tmp = init_vgmstream_from_STREAMFILE(sf);
|
auto *tmp = init_vgmstream_from_STREAMFILE(sf);
|
||||||
if (!tmp) {
|
if (!tmp) {
|
||||||
streams.push_back("");
|
streams.push_back(stream);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
reset_vgmstream(tmp);
|
reset_vgmstream(tmp);
|
||||||
|
|
||||||
|
stream.length = (double)tmp->num_samples / (double)tmp->sample_rate;
|
||||||
char *buf = (char*)malloc(STREAM_NAME_SIZE + 1);
|
char *buf = (char*)malloc(STREAM_NAME_SIZE + 1);
|
||||||
memset(buf, 0, STREAM_NAME_SIZE + 1);
|
memset(buf, 0, STREAM_NAME_SIZE + 1);
|
||||||
strncpy(buf, tmp->stream_name, STREAM_NAME_SIZE);
|
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);
|
free(buf);
|
||||||
close_vgmstream(tmp);
|
close_vgmstream(tmp);
|
||||||
}
|
}
|
||||||
|
@ -222,7 +236,7 @@ VGMSTREAM *PlaybackInstance::LoadVgm(const char *file, int idx) {
|
||||||
vgmstream_spec.channels = output->channels;
|
vgmstream_spec.channels = output->channels;
|
||||||
vgmstream_spec.freq = output->sample_rate;
|
vgmstream_spec.freq = output->sample_rate;
|
||||||
|
|
||||||
length = (double)output->num_samples / (double)output->sample_rate;
|
length = streams[idx].length;
|
||||||
update.store(true);
|
update.store(true);
|
||||||
current_file_mutex.lock();
|
current_file_mutex.lock();
|
||||||
current_file = std::string(file);
|
current_file = std::string(file);
|
||||||
|
@ -379,7 +393,7 @@ void PlaybackInstance::ThreadFunc() {
|
||||||
}
|
}
|
||||||
if (stream_changed.exchange(false)) {
|
if (stream_changed.exchange(false)) {
|
||||||
std::string file = current_file.value();
|
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) {
|
if (stream != nullptr) {
|
||||||
current_stream = stream->stream_index;
|
current_stream = stream->stream_index;
|
||||||
} else {
|
} else {
|
||||||
|
@ -718,8 +732,8 @@ Playback *Playback::Create(bool *daemon_found, bool daemon) {
|
||||||
DEBUG.writeln("Creating new playback instance.");
|
DEBUG.writeln("Creating new playback instance.");
|
||||||
return new PlaybackInstance();
|
return new PlaybackInstance();
|
||||||
}
|
}
|
||||||
std::vector<std::string> PlaybackInstance::get_streams() {
|
std::vector<PlaybackStream> PlaybackInstance::get_streams() {
|
||||||
std::vector<std::string> output;
|
std::vector<PlaybackStream> output;
|
||||||
for (auto stream : streams) {
|
for (auto stream : streams) {
|
||||||
output.push_back(stream);
|
output.push_back(stream);
|
||||||
}
|
}
|
||||||
|
|
13
playback.h
13
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.
|
/// @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
|
PlaybackSignalStarted = 1 << 9
|
||||||
};
|
};
|
||||||
|
struct PlaybackStream {
|
||||||
|
double length;
|
||||||
|
std::string name;
|
||||||
|
int id;
|
||||||
|
};
|
||||||
/// @brief Playback handler base class.
|
/// @brief Playback handler base class.
|
||||||
class Playback {
|
class Playback {
|
||||||
protected:
|
protected:
|
||||||
|
@ -83,8 +88,8 @@ class Playback {
|
||||||
inline virtual int get_current_stream() {
|
inline virtual int get_current_stream() {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
inline virtual std::vector<std::string> get_streams() {
|
inline virtual std::vector<PlaybackStream> get_streams() {
|
||||||
std::vector<std::string> output;
|
std::vector<PlaybackStream> output;
|
||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
inline virtual void play_stream(int idx) {}
|
inline virtual void play_stream(int idx) {}
|
||||||
|
@ -222,7 +227,7 @@ private:
|
||||||
void UnloadMix(Mix_Music* music);
|
void UnloadMix(Mix_Music* music);
|
||||||
void UnloadVgm(VGMSTREAM *stream);
|
void UnloadVgm(VGMSTREAM *stream);
|
||||||
VGMSTREAM *stream;
|
VGMSTREAM *stream;
|
||||||
std::vector<std::string> streams;
|
std::vector<PlaybackStream> streams;
|
||||||
std::mutex stream_list_mutex;
|
std::mutex stream_list_mutex;
|
||||||
double real_volume = 1.0;
|
double real_volume = 1.0;
|
||||||
void ThreadFunc();
|
void ThreadFunc();
|
||||||
|
@ -244,7 +249,7 @@ public:
|
||||||
inline bool is_proxy() override {
|
inline bool is_proxy() override {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
std::vector<std::string> get_streams() override;
|
std::vector<PlaybackStream> get_streams() override;
|
||||||
void play_stream(int idx) override;
|
void play_stream(int idx) override;
|
||||||
void Load(std::string filePath) override;
|
void Load(std::string filePath) override;
|
||||||
double GetPosition() override;
|
double GetPosition() override;
|
||||||
|
|
Loading…
Reference in a new issue