diff options
-rw-r--r-- | src/player.c | 17 | ||||
-rw-r--r-- | src/player.h | 3 | ||||
-rw-r--r-- | src/ui_act.c | 28 |
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); } |