diff --git a/ConfigDrafting.txt b/ConfigDrafting.txt new file mode 100644 index 0000000..d49bc4a --- /dev/null +++ b/ConfigDrafting.txt @@ -0,0 +1,27 @@ +Opensubsonic Server Settings: + +Protocol ('protocol') - Really it's either 'http' or 'https' +Server ('server') - The Opensubsonic server address, examples: + - 'server.com' + - 'music.server.com' + - 'music.server.com:4533' + - '192.168.1.5:8080' +'protocol' and 'server' are used to form the URL as 'protocol://server' +Username ('username') - Your Opensubsonic username +Password ('password') - Your Opensubsonic password + +Scrobbler Settings: +TODO + +Discord RPC Settings: +Enable ('enable') - 'true' to enable Discord RPC or 'false' to disable it +Method ('method'): + - Method '0' is the official local Discord RPC method, local application to local discord client + - Method '1' is a VERY buggy and in-development RPC method that uses a client-server model + to allow Discord RPC from a mobile device securely +Show System Details ('showSystemDetails') - 'true' or 'false' + - Want to show off / Got bragging rights on your _unique_ system?? Well this is perfect for you! + Setting this to 'true' shows the details of the operating system that OSSP is running on. + Example: 'on Linux x86_64 6.17.1-arch1-1' will be shown in the RPC dialog + Go on, don't be shy, show everyone you somehow have Discord and OSSP running on fucking s390x!!! + - Setting this to 'false' will simply instead show what playlist you are playing. diff --git a/src/discordrpc.c b/src/discordrpc.c index e2823eb..eee61a3 100644 --- a/src/discordrpc.c +++ b/src/discordrpc.c @@ -67,8 +67,6 @@ void discordrpc_init() { discordrpc_osString = discordrpc_getOS(); } -#include - void discordrpc_update(discordrpc_data** discordrpc_struct) { printf("[DiscordRPC] Updating...\n"); DiscordRichPresence presence; diff --git a/src/gui/gui_entry.cpp b/src/gui/gui_entry.cpp index b2819eb..bcd808c 100644 --- a/src/gui/gui_entry.cpp +++ b/src/gui/gui_entry.cpp @@ -12,7 +12,9 @@ extern configHandler_config_t* configObj; bool bLikedSongsShow = false; +bool bAudioSettingsShow = false; void showLikedSongs(); +void showAudioSettings(); int qt_gui_entry(int argc, char** argv) { // Initialize SDL @@ -89,6 +91,12 @@ int qt_gui_entry(int argc, char** argv) { bLikedSongsShow = true; } + ImGui::SameLine(); + + if (ImGui::Button("Audio Settings")) { + bAudioSettingsShow = true; + } + ImGui::End(); } @@ -96,6 +104,10 @@ int qt_gui_entry(int argc, char** argv) { showLikedSongs(); } + if (bAudioSettingsShow) { + showAudioSettings(); + } + // Render ImGui::Render(); glViewport(0, 0, (int)io.DisplaySize.x, (int)io.DisplaySize.y); @@ -155,13 +167,15 @@ void showLikedSongs() { } static int selectedSong = -1; - if (ImGui::BeginChild("Liked Songs", ImVec2(0, 200), ImGuiChildFlags_Border)) { - for (int i = 0; i < starredStruct->songCount; i++) { - if (ImGui::Selectable(starredStruct->songs[i].title, selectedSong == i)) { - selectedSong = i; + if (haveLikedSongsInfo) { + if (ImGui::BeginChild("Liked Songs", ImVec2(0, 200), ImGuiChildFlags_Border)) { + for (int i = 0; i < starredStruct->songCount; i++) { + if (ImGui::Selectable(starredStruct->songs[i].title, selectedSong == i)) { + selectedSong = i; + } } - } ImGui::EndChild(); + } } if (selectedSong != -1) { @@ -173,3 +187,22 @@ void showLikedSongs() { ImGui::End(); } + +float in_volume_val = 0; +bool hasInVolumeFirstRun = false; +void showAudioSettings() { + ImGui::Begin("Audio Settings"); + + if (!hasInVolumeFirstRun) { + in_volume_val = OSSPlayer_GstECont_InVolume_Get(); + hasInVolumeFirstRun = true; + } + + // Idk what that field is, styling?, Size, Storage, Low, High + if (ImGui::VSliderFloat("##v", ImVec2(35, 160), &in_volume_val, 0.0f, 1.0f)) { + // Data has changed + OSSPlayer_GstECont_InVolume_set(in_volume_val); + } + + ImGui::End(); +} diff --git a/src/player/player.c b/src/player/player.c index 5ef9af5..bb7d71c 100644 --- a/src/player/player.c +++ b/src/player/player.c @@ -10,6 +10,7 @@ #include #include #include "../configHandler.h" +#include "../discordrpc.h" #include "../libopensubsonic/logger.h" #include "../libopensubsonic/endpoint_getSong.h" #include "../libopensubsonic/httpclient.h" @@ -28,17 +29,22 @@ GMainLoop* loop; bool isPlaying = false; static gboolean gst_bus_call(GstBus* bus, GstMessage* message, gpointer data) { - printf("BUSCALL\n"); GMainLoop* loop = (GMainLoop*)data; switch (GST_MESSAGE_TYPE(message)) { case GST_MESSAGE_EOS: - printf("End of stream\n"); + logger_log_important(__func__, "[GBus] End of stream"); gst_element_set_state(pipeline, GST_STATE_NULL); isPlaying = false; break; + case GST_MESSAGE_BUFFERING: + gint percent = 0; + gst_message_parse_buffering(message, &percent); + printf("Buffering (%d%%)...\n", (int)percent); + break; case GST_MESSAGE_ERROR: printf("Error\n"); + break; default: printf("Unknown\n"); break; @@ -47,18 +53,20 @@ static gboolean gst_bus_call(GstBus* bus, GstMessage* message, gpointer data) { return TRUE; } -void* OSSPlayer_GstMainLoop(void*) { - printf("GstMainLoop running\n"); +void* OSSPlayer_GMainLoop(void*) { + logger_log_important(__func__, "GMainLoop thread running."); + // This is needed for the Gstreamer bus to work, but it hangs the thread g_main_loop_run(loop); } void* OSSPlayer_ThrdInit(void*) { // Player init function for pthread entry - printf("Player thread running.\n"); + logger_log_important(__func__, "Player thread running."); OSSPlayer_GstInit(); - pthread_t pthr_gst; - pthread_create(&pthr_gst, NULL, OSSPlayer_GstMainLoop, NULL); + // Launch GMainLoop thread + pthread_t pthr_gml; + pthread_create(&pthr_gml, NULL, OSSPlayer_GMainLoop, NULL); // Poll play queue for new items to play while (true) { // TODO use global bool instead @@ -71,12 +79,29 @@ void* OSSPlayer_ThrdInit(void*) { // TODO: this } - //opensubsonic_httpClient_URL_t* song_url = malloc(sizeof(opensubsonic_httpClient_URL_t)); - //opensubsonic_httpClient_URL_prepare(&song_url); - //song_url->endpoint = OPENSUBSONIC_ENDPOINT_GETSONG; - //song_url->id = id; - //opensubsonic_httpClient_formUrl(&song_url); + // Fetch song information + opensubsonic_httpClient_URL_t* song_url = malloc(sizeof(opensubsonic_httpClient_URL_t)); + opensubsonic_httpClient_URL_prepare(&song_url); + song_url->endpoint = OPENSUBSONIC_ENDPOINT_GETSONG; + song_url->id = strdup(id); + opensubsonic_httpClient_formUrl(&song_url); + opensubsonic_getSong_struct* songStruct; + opensubsonic_httpClient_fetchResponse(&song_url, (void**)&songStruct); + // Update Discord RPC + discordrpc_data* discordrpc = NULL; + discordrpc_struct_init(&discordrpc); + discordrpc->state = DISCORDRPC_STATE_PLAYING; + discordrpc->songTitle = strdup(songStruct->title); + discordrpc->songArtist = strdup(songStruct->artist); + //discordrpc->coverArtUrl = "https://pbs.twimg.com/profile_banners/2995329026/1758957365/1500x500"; + discordrpc_update(&discordrpc); + discordrpc_struct_deinit(&discordrpc); + + opensubsonic_getSong_struct_free(&songStruct); + opensubsonic_httpClient_URL_cleanup(&song_url); + + // Create stream URL opensubsonic_httpClient_URL_t* stream_url = malloc(sizeof(opensubsonic_httpClient_URL_t)); opensubsonic_httpClient_URL_prepare(&stream_url); stream_url->endpoint = OPENSUBSONIC_ENDPOINT_STREAM; @@ -87,7 +112,6 @@ void* OSSPlayer_ThrdInit(void*) { isPlaying = true; gst_element_set_state(pipeline, GST_STATE_PLAYING); } - printf("Sleeping\n"); usleep(200 * 1000); // Use futex and signals instead of this TODO } } @@ -230,9 +254,6 @@ int OSSPlayer_GstInit() { g_object_set(equalizer, "enabled", true, NULL); } - - //g_main_loop_run(loop); - } int OSSPlayer_GstDeInit() { @@ -249,6 +270,7 @@ int OSSPlayer_QueueAppend(char* id) { char* OSSPlayer_QueuePopFront() { // Call to C++ function + // NOTE: 'id' is heap-allocated from C++ char* id = internal_OSSPQ_PopFromFront(); if (id == NULL) { // Queue is empty TODO @@ -257,6 +279,19 @@ char* OSSPlayer_QueuePopFront() { return id; } +/* + * Gstreamer Element Control Functions + */ +float OSSPlayer_GstECont_InVolume_Get() { + gdouble vol; + g_object_get(in_volume, "volume", &vol, NULL); + return (float)vol; +} + +void OSSPlayer_GstECont_InVolume_set(float val) { + g_object_set(in_volume, "volume", val, NULL); +} + /* * Utility Functions */ diff --git a/src/player/player.h b/src/player/player.h index 70b5ba6..3e0f9be 100644 --- a/src/player/player.h +++ b/src/player/player.h @@ -5,10 +5,15 @@ extern "C" { #endif +void* OSSPlayer_GMainLoop(void*); void* OSSPlayer_ThrdInit(void*); int OSSPlayer_GstInit(); int OSSPlayer_QueueAppend(char* id); char* OSSPlayer_QueuePopFront(); + +float OSSPlayer_GstECont_InVolume_Get(); +void OSSPlayer_GstECont_InVolume_set(float val); + float OSSPlayer_DbLinMul(float db); float OSSPlayer_PitchFollow(float freq, float semitone);