Commit efde884a authored by Max Kellermann's avatar Max Kellermann

added PlayerControl.command

PlayerControl.command replaces the old attributes play, stop, pause, closeAudio, lockQueue, unlockQueue, seek. The main thread waits for each command synchronously, so there can only be one command enabled at a time anyway.
parent c7384b65
...@@ -60,9 +60,7 @@ static void quitDecode(void) ...@@ -60,9 +60,7 @@ static void quitDecode(void)
stopDecode(); stopDecode();
pc.state = PLAYER_STATE_STOP; pc.state = PLAYER_STATE_STOP;
dc.command = DECODE_COMMAND_NONE; dc.command = DECODE_COMMAND_NONE;
pc.play = 0; pc.command = PLAYER_COMMAND_NONE;
pc.stop = 0;
pc.pause = 0;
wakeup_main_task(); wakeup_main_task();
} }
...@@ -141,8 +139,8 @@ static int decodeSeek(int *decodeWaitedOn, int *next) ...@@ -141,8 +139,8 @@ static int decodeSeek(int *decodeWaitedOn, int *next)
ret = 0; ret = 0;
} }
} }
pc.seek = 0;
wakeup_main_task(); player_command_finished();
return ret; return ret;
} }
...@@ -152,17 +150,24 @@ static void processDecodeInput(int *pause_r, unsigned int *bbp_r, ...@@ -152,17 +150,24 @@ static void processDecodeInput(int *pause_r, unsigned int *bbp_r,
int *decodeWaitedOn_r, int *decodeWaitedOn_r,
int *next_r) int *next_r)
{ {
if(pc.lockQueue) { switch (pc.command) {
case PLAYER_COMMAND_NONE:
case PLAYER_COMMAND_PLAY:
case PLAYER_COMMAND_STOP:
case PLAYER_COMMAND_CLOSE_AUDIO:
break;
case PLAYER_COMMAND_LOCK_QUEUE:
pc.queueLockState = PLAYER_QUEUE_LOCKED; pc.queueLockState = PLAYER_QUEUE_LOCKED;
pc.lockQueue = 0; player_command_finished();
wakeup_main_task(); break;
}
if(pc.unlockQueue) { case PLAYER_COMMAND_UNLOCK_QUEUE:
pc.queueLockState = PLAYER_QUEUE_UNLOCKED; pc.queueLockState = PLAYER_QUEUE_UNLOCKED;
pc.unlockQueue = 0; player_command_finished();
wakeup_main_task(); break;
}
if(pc.pause) { case PLAYER_COMMAND_PAUSE:
*pause_r = !*pause_r; *pause_r = !*pause_r;
if (*pause_r) { if (*pause_r) {
pc.state = PLAYER_STATE_PAUSE; pc.state = PLAYER_STATE_PAUSE;
...@@ -179,21 +184,22 @@ static void processDecodeInput(int *pause_r, unsigned int *bbp_r, ...@@ -179,21 +184,22 @@ static void processDecodeInput(int *pause_r, unsigned int *bbp_r,
*pause_r = -1; *pause_r = -1;
} }
} }
pc.pause = 0; player_command_finished();
wakeup_main_task();
if (*pause_r == -1) { if (*pause_r == -1) {
*pause_r = 1; *pause_r = 1;
} else if (*pause_r) { } else if (*pause_r) {
dropBufferedAudio(); dropBufferedAudio();
closeAudioDevice(); closeAudioDevice();
} }
} break;
if(pc.seek) {
case PLAYER_COMMAND_SEEK:
dropBufferedAudio(); dropBufferedAudio();
if (decodeSeek(decodeWaitedOn_r, next_r) == 0) { if (decodeSeek(decodeWaitedOn_r, next_r) == 0) {
*do_xfade_r = XFADE_UNKNOWN; *do_xfade_r = XFADE_UNKNOWN;
*bbp_r = 0; *bbp_r = 0;
} }
break;
} }
} }
...@@ -410,13 +416,12 @@ static void decodeParent(void) ...@@ -410,13 +416,12 @@ static void decodeParent(void)
pc.elapsedTime = 0; pc.elapsedTime = 0;
pc.state = PLAYER_STATE_PLAY; pc.state = PLAYER_STATE_PLAY;
pc.play = 0; player_command_finished();
wakeup_main_task();
while (1) { while (1) {
processDecodeInput(&do_pause, &bbp, &do_xfade, processDecodeInput(&do_pause, &bbp, &do_xfade,
&decodeWaitedOn, &next); &decodeWaitedOn, &next);
if (pc.stop) { if (pc.command == PLAYER_COMMAND_STOP) {
dropBufferedAudio(); dropBufferedAudio();
break; break;
} }
......
...@@ -28,41 +28,41 @@ ...@@ -28,41 +28,41 @@
static void playerCloseAudio(void); static void playerCloseAudio(void);
static void wakeup_player(void)
{
notify_signal(&pc.notify);
wait_main_task();
}
static void * player_task(mpd_unused void *arg) static void * player_task(mpd_unused void *arg)
{ {
notify_enter(&pc.notify); notify_enter(&pc.notify);
while (1) { while (1) {
if (pc.play) { switch (pc.command) {
case PLAYER_COMMAND_PLAY:
decode(); decode();
continue; /* decode() calls wakeup_main_task */ break;
} else if (pc.stop) {
pc.stop = 0; case PLAYER_COMMAND_STOP:
} else if (pc.seek) { case PLAYER_COMMAND_SEEK:
pc.seek = 0; case PLAYER_COMMAND_PAUSE:
} else if (pc.pause) { player_command_finished();
pc.pause = 0; break;
} else if (pc.closeAudio) {
case PLAYER_COMMAND_CLOSE_AUDIO:
closeAudioDevice(); closeAudioDevice();
pc.closeAudio = 0; player_command_finished();
} else if (pc.lockQueue) { break;
case PLAYER_COMMAND_LOCK_QUEUE:
pc.queueLockState = PLAYER_QUEUE_LOCKED; pc.queueLockState = PLAYER_QUEUE_LOCKED;
pc.lockQueue = 0; player_command_finished();
} else if (pc.unlockQueue) { break;
case PLAYER_COMMAND_UNLOCK_QUEUE:
pc.queueLockState = PLAYER_QUEUE_UNLOCKED; pc.queueLockState = PLAYER_QUEUE_UNLOCKED;
pc.unlockQueue = 0; player_command_finished();
} else { break;
case PLAYER_COMMAND_NONE:
notify_wait(&pc.notify); notify_wait(&pc.notify);
continue; break;
} }
/* we did something, tell the main task about it */
wakeup_main_task();
} }
return NULL; return NULL;
} }
...@@ -94,26 +94,37 @@ static void set_current_song(Song *song) ...@@ -94,26 +94,37 @@ static void set_current_song(Song *song)
pc.next_song = song; pc.next_song = song;
} }
static void player_command(enum player_command cmd)
{
pc.command = cmd;
while (pc.command != PLAYER_COMMAND_NONE)
/* FIXME: _nb() variant is probably wrong here, and everywhere... */
notify_signal(&pc.notify);
}
void player_command_finished()
{
assert(pc.command != PLAYER_COMMAND_NONE);
pc.command = PLAYER_COMMAND_NONE;
wakeup_main_task();
}
int playerPlay(int fd, Song * song) int playerPlay(int fd, Song * song)
{ {
if (playerStop(fd) < 0) if (playerStop(fd) < 0)
return -1; return -1;
set_current_song(song); set_current_song(song);
player_command(PLAYER_COMMAND_PLAY);
pc.play = 1;
/* FIXME: _nb() variant is probably wrong here, and everywhere... */
do { notify_signal(&pc.notify); } while (pc.play);
return 0; return 0;
} }
int playerStop(mpd_unused int fd) int playerStop(mpd_unused int fd)
{ {
if (pc.state != PLAYER_STATE_STOP) { if (pc.state != PLAYER_STATE_STOP)
pc.stop = 1; player_command(PLAYER_COMMAND_STOP);
do { wakeup_player(); } while (pc.stop);
}
pc.queueState = PLAYER_QUEUE_BLANK; pc.queueState = PLAYER_QUEUE_BLANK;
playerQueueUnlock(); playerQueueUnlock();
...@@ -128,10 +139,8 @@ void playerKill(void) /* deprecated */ ...@@ -128,10 +139,8 @@ void playerKill(void) /* deprecated */
int playerPause(mpd_unused int fd) int playerPause(mpd_unused int fd)
{ {
if (pc.state != PLAYER_STATE_STOP) { if (pc.state != PLAYER_STATE_STOP)
pc.pause = 1; player_command(PLAYER_COMMAND_PAUSE);
do { wakeup_player(); } while (pc.pause);
}
return 0; return 0;
} }
...@@ -217,8 +226,8 @@ static void playerCloseAudio(void) ...@@ -217,8 +226,8 @@ static void playerCloseAudio(void)
{ {
if (playerStop(STDERR_FILENO) < 0) if (playerStop(STDERR_FILENO) < 0)
return; return;
pc.closeAudio = 1;
do { wakeup_player(); } while (pc.closeAudio); player_command(PLAYER_COMMAND_CLOSE_AUDIO);
} }
int queueSong(Song * song) int queueSong(Song * song)
...@@ -245,18 +254,14 @@ void setQueueState(int queueState) ...@@ -245,18 +254,14 @@ void setQueueState(int queueState)
void playerQueueLock(void) void playerQueueLock(void)
{ {
if (pc.queueLockState == PLAYER_QUEUE_UNLOCKED) { if (pc.queueLockState == PLAYER_QUEUE_UNLOCKED)
pc.lockQueue = 1; player_command(PLAYER_COMMAND_LOCK_QUEUE);
do { wakeup_player(); } while (pc.lockQueue);
}
} }
void playerQueueUnlock(void) void playerQueueUnlock(void)
{ {
if (pc.queueLockState == PLAYER_QUEUE_LOCKED) { if (pc.queueLockState == PLAYER_QUEUE_LOCKED)
pc.unlockQueue = 1; player_command(PLAYER_COMMAND_UNLOCK_QUEUE);
do { wakeup_player(); } while (pc.unlockQueue);
}
} }
int playerSeek(int fd, Song * song, float seek_time) int playerSeek(int fd, Song * song, float seek_time)
...@@ -274,9 +279,7 @@ int playerSeek(int fd, Song * song, float seek_time) ...@@ -274,9 +279,7 @@ int playerSeek(int fd, Song * song, float seek_time)
if (pc.error == PLAYER_ERROR_NOERROR) { if (pc.error == PLAYER_ERROR_NOERROR) {
pc.seekWhere = seek_time; pc.seekWhere = seek_time;
pc.seek = 1; player_command(PLAYER_COMMAND_SEEK);
/* FIXME: _nb() is probably wrong here, too */
do { notify_signal(&pc.notify); } while (pc.seek);
} }
return 0; return 0;
......
...@@ -28,6 +28,17 @@ ...@@ -28,6 +28,17 @@
#define PLAYER_STATE_PAUSE 1 #define PLAYER_STATE_PAUSE 1
#define PLAYER_STATE_PLAY 2 #define PLAYER_STATE_PLAY 2
enum player_command {
PLAYER_COMMAND_NONE = 0,
PLAYER_COMMAND_STOP,
PLAYER_COMMAND_PLAY,
PLAYER_COMMAND_PAUSE,
PLAYER_COMMAND_SEEK,
PLAYER_COMMAND_CLOSE_AUDIO,
PLAYER_COMMAND_LOCK_QUEUE,
PLAYER_COMMAND_UNLOCK_QUEUE
};
#define PLAYER_ERROR_NOERROR 0 #define PLAYER_ERROR_NOERROR 0
#define PLAYER_ERROR_FILE 1 #define PLAYER_ERROR_FILE 1
#define PLAYER_ERROR_AUDIO 2 #define PLAYER_ERROR_AUDIO 2
...@@ -50,11 +61,8 @@ ...@@ -50,11 +61,8 @@
typedef struct _PlayerControl { typedef struct _PlayerControl {
Notify notify; Notify notify;
volatile mpd_sint8 stop; volatile enum player_command command;
volatile mpd_sint8 play;
volatile mpd_sint8 pause;
volatile mpd_sint8 state; volatile mpd_sint8 state;
volatile mpd_sint8 closeAudio;
volatile mpd_sint8 error; volatile mpd_sint8 error;
volatile mpd_uint16 bitRate; volatile mpd_uint16 bitRate;
volatile mpd_sint8 bits; volatile mpd_sint8 bits;
...@@ -67,15 +75,14 @@ typedef struct _PlayerControl { ...@@ -67,15 +75,14 @@ typedef struct _PlayerControl {
Song *errored_song; Song *errored_song;
volatile mpd_sint8 queueState; volatile mpd_sint8 queueState;
volatile mpd_sint8 queueLockState; volatile mpd_sint8 queueLockState;
volatile mpd_sint8 lockQueue;
volatile mpd_sint8 unlockQueue;
volatile mpd_sint8 seek;
volatile double seekWhere; volatile double seekWhere;
volatile float crossFade; volatile float crossFade;
volatile mpd_uint16 softwareVolume; volatile mpd_uint16 softwareVolume;
volatile double totalPlayTime; volatile double totalPlayTime;
} PlayerControl; } PlayerControl;
void player_command_finished(void);
int playerPlay(int fd, Song * song); int playerPlay(int fd, Song * song);
int playerSetPause(int fd, int pause_flag); int playerSetPause(int fd, int pause_flag);
......
...@@ -75,6 +75,7 @@ void initPlayerData(void) ...@@ -75,6 +75,7 @@ void initPlayerData(void)
ob_init(buffered_chunks, &pc.notify); ob_init(buffered_chunks, &pc.notify);
notify_init(&pc.notify); notify_init(&pc.notify);
pc.command = PLAYER_COMMAND_NONE;
pc.error = PLAYER_ERROR_NOERROR; pc.error = PLAYER_ERROR_NOERROR;
pc.state = PLAYER_STATE_STOP; pc.state = PLAYER_STATE_STOP;
pc.queueState = PLAYER_QUEUE_BLANK; pc.queueState = PLAYER_QUEUE_BLANK;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment