Reworked GStreamer play queue system, now actually works

This commit is contained in:
2026-03-21 09:45:09 +10:00
parent 0fbd08ef69
commit b4351b8f48
4 changed files with 92 additions and 3 deletions
+56
View File
@@ -19,6 +19,8 @@
#include <deque> #include <deque>
#include "playQueue.hpp" #include "playQueue.hpp"
int OSSPQ_currentPos = 0;
// C++ interface for storing song queue data (C interface is in the header) // C++ interface for storing song queue data (C interface is in the header)
class OSSPQ_SongObject { class OSSPQ_SongObject {
public: public:
@@ -66,6 +68,7 @@ int OSSPQ_AppendToEnd(char* title, char* album, char* artist, char* id, char* st
return 0; return 0;
} }
/*
OSSPQ_SongStruct* OSSPQ_PopFromFront() { OSSPQ_SongStruct* OSSPQ_PopFromFront() {
// Check if song queue is empty, if not, then pop oldest // Check if song queue is empty, if not, then pop oldest
if (OSSPQ_SongQueue.empty()) { if (OSSPQ_SongQueue.empty()) {
@@ -102,6 +105,59 @@ OSSPQ_SongStruct* OSSPQ_PopFromFront() {
return songObjectC; return songObjectC;
} }
*/
int OSSPQ_getCurrentPos() {
return OSSPQ_currentPos;
}
int OSSPQ_getTotalPos() {
return OSSPQ_SongQueue.size();
}
int OSSPQ_advancePos() {
OSSPQ_currentPos += 1;
}
int OSSPQ_backtrackPos() {
OSSPQ_currentPos -= 1;
}
OSSPQ_SongStruct* OSSPQ_getAtPos(int pos) {
// Check if song queue is empty, if not, then pop oldest
if (OSSPQ_SongQueue.empty()) {
return NULL;
}
OSSPQ_SongObject songObject = OSSPQ_SongQueue[pos];
// Allocate, initialize, and fill C compatible song object
OSSPQ_SongStruct* songObjectC = (OSSPQ_SongStruct*)malloc(sizeof(OSSPQ_SongStruct));
songObjectC->title = NULL;
songObjectC->album = NULL;
songObjectC->artist = NULL;
songObjectC->id = NULL;
songObjectC->streamUrl = NULL;
songObjectC->coverArtUrl = NULL;
songObjectC->duration = 0;
songObjectC->mode = 0;
if (songObject.mode == OSSPQ_MODE_OPENSUBSONIC || songObject.mode == OSSPQ_MODE_LOCALFILE) {
songObjectC->title = strdup(songObject.title.c_str());
songObjectC->album = strdup(songObject.album.c_str());
songObjectC->artist = strdup(songObject.artist.c_str());
songObjectC->id = strdup(songObject.id.c_str());
songObjectC->streamUrl = strdup(songObject.streamUrl.c_str());
songObjectC->coverArtUrl = strdup(songObject.coverArtUrl.c_str());
songObjectC->duration = songObject.duration;
songObjectC->mode = songObject.mode;
} else if (songObject.mode == OSSPQ_MODE_INTERNETRADIO) {
songObjectC->title = strdup(songObject.title.c_str());
songObjectC->id = strdup(songObject.id.c_str());
songObjectC->streamUrl = strdup(songObject.streamUrl.c_str());
}
return songObjectC;
}
void OSSPQ_FreeSongObjectC(OSSPQ_SongStruct* songObjectC) { void OSSPQ_FreeSongObjectC(OSSPQ_SongStruct* songObjectC) {
printf("[OSSPQ] Freeing SongObjectC.\n"); printf("[OSSPQ] Freeing SongObjectC.\n");
+8 -1
View File
@@ -28,13 +28,20 @@ typedef struct {
} OSSPQ_SongStruct; } OSSPQ_SongStruct;
int OSSPQ_AppendToEnd(char* title, char* album, char* artist, char* id, char* streamUrl, char* coverArtUrl, long duration, int mode); int OSSPQ_AppendToEnd(char* title, char* album, char* artist, char* id, char* streamUrl, char* coverArtUrl, long duration, int mode);
OSSPQ_SongStruct* OSSPQ_PopFromFront(); //OSSPQ_SongStruct* OSSPQ_PopFromFront();
void OSSPQ_FreeSongObjectC(OSSPQ_SongStruct* songObjectC); void OSSPQ_FreeSongObjectC(OSSPQ_SongStruct* songObjectC);
// TODO // TODO
char* internal_OSSPQ_GetTitleAtIndex(int idx); char* internal_OSSPQ_GetTitleAtIndex(int idx);
int internal_OSSPQ_GetItemCount(); int internal_OSSPQ_GetItemCount();
// Testing
int OSSPQ_getCurrentPos();
int OSSPQ_getTotalPos();
int OSSPQ_advancePos();
int OSSPQ_backtrackPos();
OSSPQ_SongStruct* OSSPQ_getAtPos(int pos);
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif // __cplusplus #endif // __cplusplus
+25 -2
View File
@@ -38,6 +38,7 @@ static gboolean gst_bus_call(GstBus* bus, GstMessage* message, gpointer data) {
switch (GST_MESSAGE_TYPE(message)) { switch (GST_MESSAGE_TYPE(message)) {
case GST_MESSAGE_EOS: case GST_MESSAGE_EOS:
logger_log_important(__func__, "[GBus] End of stream"); logger_log_important(__func__, "[GBus] End of stream");
OSSPQ_advancePos(); // Move to next song in queue
gst_element_set_state(pipeline, GST_STATE_NULL); gst_element_set_state(pipeline, GST_STATE_NULL);
isPlaying = false; isPlaying = false;
break; break;
@@ -122,7 +123,7 @@ void* OSSPlayer_ThrdInit(void* arg) {
// Player is not playing and a song is in the song queue // Player is not playing and a song is in the song queue
// Pull new song from the song queue // Pull new song from the song queue
OSSPQ_SongStruct* songObject = OSSPQ_PopFromFront(); OSSPQ_SongStruct* songObject = OSSPQ_getAtPos(OSSPQ_getCurrentPos());
if (songObject == NULL) { if (songObject == NULL) {
// Severe error - There was an item in the queue, but fetching it didn't work // Severe error - There was an item in the queue, but fetching it didn't work
printf("[OSSPlayer]\n"); printf("[OSSPlayer]\n");
@@ -189,7 +190,8 @@ void* OSSPlayer_ThrdInit(void* arg) {
} }
} }
if (internal_OSSPQ_GetItemCount() == 0 && !isPlaying) { //if (internal_OSSPQ_GetItemCount() == 0 && !isPlaying) {
if (OSSPQ_getCurrentPos() != OSSPQ_getTotalPos() && !isPlaying) {
// No song currently playing, and the queue is empty // No song currently playing, and the queue is empty
// Only send idle Discord RPC if needed to avoid spamming // Only send idle Discord RPC if needed to avoid spamming
@@ -430,10 +432,15 @@ void OSSPlayer_GstECont_Pitch_Set(float cents) {
} }
void OSSPlayer_GstECont_Playbin3_Stop() { void OSSPlayer_GstECont_Playbin3_Stop() {
OSSPQ_advancePos();
gst_element_set_state(pipeline, GST_STATE_NULL); // Stop playbin3 gst_element_set_state(pipeline, GST_STATE_NULL); // Stop playbin3
isPlaying = false; // Notify player thread to attempt to load next song isPlaying = false; // Notify player thread to attempt to load next song
} }
void OSSPlayer_GstECont_Playbin3_PlayPause() { void OSSPlayer_GstECont_Playbin3_PlayPause() {
GstState state; GstState state;
gst_element_get_state (pipeline, &state, NULL, 0); gst_element_get_state (pipeline, &state, NULL, 0);
@@ -447,6 +454,22 @@ void OSSPlayer_GstECont_Playbin3_PlayPause() {
} }
} }
void OSSPlayer_GstECont_Playbin3_Prev() {
// Move queue back by one, then stop playbin3 and notify player thread
printf("[OSSPP] Moving the player queue back by one.\n");
OSSPQ_backtrackPos();
gst_element_set_state(pipeline, GST_STATE_NULL);
isPlaying = false;
}
void OSSPlayer_GstECont_Playbin3_Next() {
// Same as *Playbin3_Prev(), but advance queue by one
printf("[OSSPP] Moving the player forward back by one.\n");
OSSPQ_advancePos();
gst_element_set_state(pipeline, GST_STATE_NULL);
isPlaying = false;
}
/* /*
* Utility Functions * Utility Functions
*/ */
+3
View File
@@ -29,6 +29,9 @@ void OSSPlayer_GstECont_Pitch_Set(float cents);
void OSSPlayer_GstECont_Playbin3_Stop(); void OSSPlayer_GstECont_Playbin3_Stop();
void OSSPlayer_GstECont_Playbin3_PlayPause(); void OSSPlayer_GstECont_Playbin3_PlayPause();
void OSSPlayer_GstECont_Playbin3_Prev();
void OSSPlayer_GstECont_Playbin3_Next();
float OSSPlayer_DbLinMul(float db); float OSSPlayer_DbLinMul(float db);
float OSSPlayer_PitchFollow(float freq, float semitone); float OSSPlayer_PitchFollow(float freq, float semitone);
float OSSPlayer_CentsToPSF(float cents); float OSSPlayer_CentsToPSF(float cents);