summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/player.c17
-rw-r--r--src/player.h3
-rw-r--r--src/ui_act.c28
3 files changed, 30 insertions, 18 deletions
diff --git a/src/player.c b/src/player.c
index b7526e4..7482cc0 100644
--- a/src/player.c
+++ b/src/player.c
@@ -34,18 +34,13 @@ THE SOFTWARE.
#define byteswap32(x) (((x >> 24) & 0x000000ff) | ((x >> 8) & 0x0000ff00) | \
((x << 8) & 0x00ff0000) | ((x << 24) & 0xff000000))
-/* FIXME: not the best solution to poll every second, but the easiest
- * one I know... (pthread's conditions could be another solution) */
+/* wait while locked, but don't slow down main thread by keeping
+* locks too long */
#define QUIT_PAUSE_CHECK \
+ pthread_mutex_lock (&player->pauseMutex); \
+ pthread_mutex_unlock (&player->pauseMutex); \
if (player->doQuit) { \
return 0; \
- } \
- if (player->doPause) { \
- curl_easy_pause (player->audioFd, CURLPAUSE_ALL); \
- while (player->doPause && !player->doQuit) { \
- sleep (1); \
- } \
- curl_easy_pause (player->audioFd, CURLPAUSE_CONT); \
}
/* compute replaygain scale factor
@@ -225,6 +220,8 @@ size_t BarPlayerCurlCb (void *ptr, size_t size, size_t nmemb, void *stream) {
(player->bufferFilled - player->bufferRead));
player->bufferFilled = (player->bufferFilled - player->bufferRead);
+ pthread_mutex_unlock (&player->pauseMutex);
+
return size*nmemb;
}
@@ -239,6 +236,7 @@ void *BarPlayerThread (void *data) {
CURLcode curlRet = 0;
/* init handles */
+ pthread_mutex_init (&player->pauseMutex, NULL);
player->audioFd = curl_easy_init ();
player->aacHandle = NeAACDecOpen();
@@ -279,6 +277,7 @@ void *BarPlayerThread (void *data) {
if (player->sampleSize != NULL) {
free (player->sampleSize);
}
+ pthread_mutex_destroy (&player->pauseMutex);
player->mode = PLAYER_FINISHED_PLAYBACK;
diff --git a/src/player.h b/src/player.h
index c210c09..7756d0a 100644
--- a/src/player.h
+++ b/src/player.h
@@ -27,6 +27,7 @@ THE SOFTWARE.
#include <curl/curl.h>
#include <neaacdec.h>
#include <ao/ao.h>
+#include <pthread.h>
struct aacPlayer {
/* buffer; should be large enough */
@@ -52,7 +53,7 @@ struct aacPlayer {
ao_device *audioOutDevice;
char *url;
char doQuit;
- char doPause;
+ pthread_mutex_t pauseMutex;
CURL *audioFd;
};
diff --git a/src/ui_act.c b/src/ui_act.c
index ae42164..5c28672 100644
--- a/src/ui_act.c
+++ b/src/ui_act.c
@@ -25,6 +25,7 @@ THE SOFTWARE.
#include <string.h>
#include <unistd.h>
+#include <pthread.h>
/* needed by readline */
#include <stdio.h>
#include <readline/readline.h>
@@ -40,6 +41,14 @@ THE SOFTWARE.
BarUiMsg ("No song playing.\n"); \
return; }
+/* helper to _really_ skip a song (unlock mutex, quit player)
+ * @param player handle
+ */
+inline void BarUiDoSkipSong (struct aacPlayer *player) {
+ player->doQuit = 1;
+ pthread_mutex_unlock (&player->pauseMutex);
+}
+
/* transform station if necessary to allow changes like rename, rate, ...
* @param piano handle
* @param transform this station
@@ -101,7 +110,7 @@ void BarUiActBanSong (BAR_KS_ARGS) {
BarUiMsg ("Banning song... ");
if (BarUiPrintPianoStatus (PianoRateTrack (ph, *curSong,
PIANO_RATE_BAN)) == PIANO_RET_OK) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
}
}
@@ -130,7 +139,7 @@ void BarUiActDeleteStation (BAR_KS_ARGS) {
BarUiMsg ("Deleting station... ");
if (BarUiPrintPianoStatus (PianoDeleteStation (ph,
*curStation)) == PIANO_RET_OK) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
PianoDestroyPlaylist (ph);
*curSong = NULL;
*curStation = NULL;
@@ -202,7 +211,7 @@ void BarUiActLoveSong (BAR_KS_ARGS) {
/* skip song
*/
void BarUiActSkipSong (BAR_KS_ARGS) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
}
/* move song to different station
@@ -227,7 +236,7 @@ void BarUiActMoveSong (BAR_KS_ARGS) {
}
if (BarUiPrintPianoStatus (PianoMoveSong (ph, fromStation,
moveStation, *curSong)) == PIANO_RET_OK) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
}
}
}
@@ -235,7 +244,10 @@ void BarUiActMoveSong (BAR_KS_ARGS) {
/* pause
*/
void BarUiActPause (BAR_KS_ARGS) {
- player->doPause = !player->doPause;
+ /* already locked => unlock/unpause */
+ if (pthread_mutex_trylock (&player->pauseMutex) == EBUSY) {
+ pthread_mutex_unlock (&player->pauseMutex);
+ }
}
/* rename current station
@@ -261,7 +273,7 @@ void BarUiActRenameStation (BAR_KS_ARGS) {
/* play another station
*/
void BarUiActSelectStation (BAR_KS_ARGS) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
PianoDestroyPlaylist (ph);
*curSong = NULL;
*curStation = BarUiSelectStation (ph, "Select station: ");
@@ -281,7 +293,7 @@ void BarUiActTempBanSong (BAR_KS_ARGS) {
BarUiMsg ("Putting song on shelf... ");
if (BarUiPrintPianoStatus (PianoSongTired (ph, *curSong)) ==
PIANO_RET_OK) {
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
}
}
@@ -328,5 +340,5 @@ void BarUiActSelectQuickMix (BAR_KS_ARGS) {
*/
void BarUiActQuit (BAR_KS_ARGS) {
*doQuit = 1;
- player->doQuit = 1;
+ BarUiDoSkipSong (player);
}