diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/main.c | 2 | ||||
| -rw-r--r-- | src/player.c | 54 | ||||
| -rw-r--r-- | src/player.h | 6 | ||||
| -rw-r--r-- | src/settings.h | 4 | ||||
| -rw-r--r-- | src/ui_act.c | 36 | ||||
| -rw-r--r-- | src/ui_act.h | 4 | ||||
| -rw-r--r-- | src/ui_dispatch.h | 14 | 
7 files changed, 83 insertions, 37 deletions
@@ -269,6 +269,7 @@ static void BarMainStartPlayback (BarApp_t *app, pthread_t *playerThread) {  		app->player.audioFormat = app->playlist->audioFormat;  		app->player.settings = &app->settings;  		pthread_mutex_init (&app->player.pauseMutex, NULL); +		pthread_cond_init (&app->player.pauseCond, NULL);  		/* throw event */  		BarUiStartEventCmd (&app->settings, "songstart", @@ -296,6 +297,7 @@ static void BarMainPlayerCleanup (BarApp_t *app, pthread_t *playerThread) {  	/* FIXME: pthread_join blocks everything if network connection  	 * is hung up e.g. */  	pthread_join (*playerThread, &threadRet); +	pthread_cond_destroy (&app->player.pauseCond);  	pthread_mutex_destroy (&app->player.pauseMutex);  	/* don't continue playback if thread reports error */ diff --git a/src/player.c b/src/player.c index 1cb44de..8a46f31 100644 --- a/src/player.c +++ b/src/player.c @@ -1,5 +1,5 @@  /* -Copyright (c) 2008-2012 +Copyright (c) 2008-2013  	Lars-Dominik Braun <lars@6xq.net>  Permission is hereby granted, free of charge, to any person obtaining a copy @@ -38,20 +38,34 @@ THE SOFTWARE.  #define bigToHostEndian32(x) ntohl(x) -/* 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) { \ -		/* err => abort playback */ \ -		return WAITRESS_CB_RET_ERR; \ -	} -  /* pandora uses float values with 2 digits precision. Scale them by 100 to get   * a "nice" integer */  #define RG_SCALE_FACTOR 100 +/*	wait until the pause flag is cleared + *	@param player structure + *	@return true if the player should quit + */ +static bool BarPlayerCheckPauseQuit (struct audioPlayer *player) { +	bool quit = false; + +	pthread_mutex_lock (&player->pauseMutex); +	while (true) { +		if (player->doQuit) { +			quit = true; +			break; +		} +		if (!player->doPause) { +			break; +		} +		pthread_cond_wait(&player->pauseCond, +				  &player->pauseMutex); +	} +	pthread_mutex_unlock (&player->pauseMutex); + +	return quit; +} +  /*	compute replaygain scale factor   *	algo taken from here: http://www.dsprelated.com/showmessage/29246/1.php   *	mpd does the same @@ -125,9 +139,8 @@ static WaitressCbReturn_t BarPlayerAACCb (void *ptr, size_t size,  	const char *data = ptr;  	struct audioPlayer *player = stream; -	QUIT_PAUSE_CHECK; - -	if (!BarPlayerBufferFill (player, data, size)) { +	if (BarPlayerCheckPauseQuit (player) || +			!BarPlayerBufferFill (player, data, size)) {  		return WAITRESS_CB_RET_ERR;  	} @@ -141,7 +154,9 @@ static WaitressCbReturn_t BarPlayerAACCb (void *ptr, size_t size,  			player->sampleSize[player->sampleSizeCurr]) {  			/* going through this loop can take up to a few seconds =>  			 * allow earlier thread abort */ -			QUIT_PAUSE_CHECK; +			if (BarPlayerCheckPauseQuit (player)) { +				return WAITRESS_CB_RET_ERR; +			}  			/* decode frame */  			aacDecoded = NeAACDecDecode(player->aacHandle, &frameInfo, @@ -335,9 +350,8 @@ static WaitressCbReturn_t BarPlayerMp3Cb (void *ptr, size_t size,  	struct audioPlayer *player = stream;  	size_t i; -	QUIT_PAUSE_CHECK; - -	if (!BarPlayerBufferFill (player, data, size)) { +	if (BarPlayerCheckPauseQuit (player) || +			!BarPlayerBufferFill (player, data, size)) {  		return WAITRESS_CB_RET_ERR;  	} @@ -417,7 +431,9 @@ static WaitressCbReturn_t BarPlayerMp3Cb (void *ptr, size_t size,  					(unsigned long long int) player->samplerate;  		} -		QUIT_PAUSE_CHECK; +		if (BarPlayerCheckPauseQuit (player)) { +			return WAITRESS_CB_RET_ERR; +		}  	} while (player->mp3Stream.error != MAD_ERROR_BUFLEN);  	player->bufferRead += player->mp3Stream.next_frame - player->buffer; diff --git a/src/player.h b/src/player.h index ac6853c..d0eac22 100644 --- a/src/player.h +++ b/src/player.h @@ -1,5 +1,5 @@  /* -Copyright (c) 2008-2010 +Copyright (c) 2008-2013  	Lars-Dominik Braun <lars@6xq.net>  Permission is hereby granted, free of charge, to any person obtaining a copy @@ -49,7 +49,8 @@ THE SOFTWARE.  #define BAR_PLAYER_BUFSIZE (WAITRESS_BUFFER_SIZE*2)  struct audioPlayer { -	char doQuit; +	bool doQuit; /* protected by pauseMutex */ +	bool doPause; /* protected by pauseMutex */  	unsigned char channels;  	unsigned char aoError; @@ -102,6 +103,7 @@ struct audioPlayer {  	unsigned char *buffer;  	pthread_mutex_t pauseMutex; +	pthread_cond_t pauseCond;  	WaitressHandle_t waith;  }; diff --git a/src/settings.h b/src/settings.h index 6ccad5d..392ea58 100644 --- a/src/settings.h +++ b/src/settings.h @@ -57,8 +57,10 @@ typedef enum {  	BAR_KS_MANAGESTATION = 23,  	BAR_KS_PLAYPAUSE2 = 24,  	BAR_KS_CREATESTATIONFROMSONG = 25, +        BAR_KS_PLAY = 26, +        BAR_KS_PAUSE = 27,  	/* insert new shortcuts _before_ this element and increase its value */ -	BAR_KS_COUNT = 26, +	BAR_KS_COUNT = 28,  } BarKeyShortcutId_t;  #define BAR_KS_DISABLED '\x00' diff --git a/src/ui_act.c b/src/ui_act.c index 70fbc9a..8d9ac09 100644 --- a/src/ui_act.c +++ b/src/ui_act.c @@ -1,5 +1,5 @@  /* -Copyright (c) 2008-2012 +Copyright (c) 2008-2013  	Lars-Dominik Braun <lars@6xq.net>  Permission is hereby granted, free of charge, to any person obtaining a copy @@ -49,9 +49,9 @@ THE SOFTWARE.  static inline void BarUiDoSkipSong (struct audioPlayer *player) {  	assert (player != NULL); -	player->doQuit = 1; -	/* unlocking an unlocked mutex is forbidden by some implementations */ -	pthread_mutex_trylock (&player->pauseMutex); +	pthread_mutex_lock (&player->pauseMutex); +	player->doQuit = true; +	pthread_cond_broadcast (&player->pauseCond);  	pthread_mutex_unlock (&player->pauseMutex);  } @@ -335,13 +335,31 @@ BarUiActCallback(BarUiActSkipSong) {  	BarUiDoSkipSong (&app->player);  } +/*	play + */ +BarUiActCallback(BarUiActPlay) { +	pthread_mutex_lock (&app->player.pauseMutex); +	app->player.doPause = false; +	pthread_cond_broadcast (&app->player.pauseCond); +	pthread_mutex_unlock (&app->player.pauseMutex); +} +  /*	pause   */  BarUiActCallback(BarUiActPause) { -	/* already locked => unlock/unpause */ -	if (pthread_mutex_trylock (&app->player.pauseMutex) == EBUSY) { -		pthread_mutex_unlock (&app->player.pauseMutex); -	} +	pthread_mutex_lock (&app->player.pauseMutex); +	app->player.doPause = true; +	pthread_cond_broadcast (&app->player.pauseCond); +	pthread_mutex_unlock (&app->player.pauseMutex); +} + +/*	toggle pause + */ +BarUiActCallback(BarUiActTogglePause) { +	pthread_mutex_lock (&app->player.pauseMutex); +	app->player.doPause = !app->player.doPause; +	pthread_cond_broadcast (&app->player.pauseCond); +	pthread_mutex_unlock (&app->player.pauseMutex);  }  /*	rename current station @@ -483,7 +501,7 @@ BarUiActCallback(BarUiActSelectQuickMix) {  /*	quit   */  BarUiActCallback(BarUiActQuit) { -	app->doQuit = 1; +	app->doQuit = true;  	BarUiDoSkipSong (&app->player);  } diff --git a/src/ui_act.h b/src/ui_act.h index d225556..3e6c4c5 100644 --- a/src/ui_act.h +++ b/src/ui_act.h @@ -1,5 +1,5 @@  /* -Copyright (c) 2008-2011 +Copyright (c) 2008-2013  	Lars-Dominik Braun <lars@6xq.net>  Permission is hereby granted, free of charge, to any person obtaining a copy @@ -45,7 +45,9 @@ BarUiActCallback(BarUiActStationFromGenre);  BarUiActCallback(BarUiActSongInfo);  BarUiActCallback(BarUiActLoveSong);  BarUiActCallback(BarUiActSkipSong); +BarUiActCallback(BarUiActPlay);  BarUiActCallback(BarUiActPause); +BarUiActCallback(BarUiActTogglePause);  BarUiActCallback(BarUiActRenameStation);  BarUiActCallback(BarUiActSelectStation);  BarUiActCallback(BarUiActTempBanSong); diff --git a/src/ui_dispatch.h b/src/ui_dispatch.h index 9d87659..6b96ae3 100644 --- a/src/ui_dispatch.h +++ b/src/ui_dispatch.h @@ -1,5 +1,5 @@  /* -Copyright (c) 2010-2012 +Copyright (c) 2010-2013  	Lars-Dominik Braun <lars@6xq.net>  Permission is hereby granted, free of charge, to any person obtaining a copy @@ -71,8 +71,8 @@ static const BarUiDispatchAction_t dispatchActions[BAR_KS_COUNT] = {  				"act_addshared"},  		{'n', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActSkipSong, "next song",  				"act_songnext"}, -		{'p', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPause, "pause/continue", -				"act_songpause"}, +		{'p', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActTogglePause, "pause/resume playback", +				"act_songpausetoggle"},  		{'q', BAR_DC_GLOBAL, BarUiActQuit, "quit", "act_quit"},  		{'r', BAR_DC_STATION, BarUiActRenameStation, "rename station",  				"act_stationrename"}, @@ -93,10 +93,14 @@ static const BarUiDispatchAction_t dispatchActions[BAR_KS_COUNT] = {  				"act_volup"},  		{'=', BAR_DC_STATION, BarUiActManageStation, "delete seeds/feedback",  				"act_managestation"}, -		{' ', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPause, NULL, -				"act_songpause2"}, +		{' ', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActTogglePause, NULL, +				"act_songpausetoggle2"},  		{'v', BAR_DC_SONG, BarUiActCreateStationFromSong,  				"create new station from song or artist", "act_stationcreatefromsong"}, +		{'P', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPlay, "resume playback", +				"act_songplay"}, +		{'S', BAR_DC_GLOBAL | BAR_DC_STATION, BarUiActPause, "pause playback", +				"act_songpause"},  		};  #include <piano.h>  | 
