PlayerControl: use strictly typed enums
This commit is contained in:
parent
6765901687
commit
d05bb2a0af
@ -124,13 +124,13 @@ handle_status(Client *client,
|
|||||||
const auto player_status = client->player_control->GetStatus();
|
const auto player_status = client->player_control->GetStatus();
|
||||||
|
|
||||||
switch (player_status.state) {
|
switch (player_status.state) {
|
||||||
case PLAYER_STATE_STOP:
|
case PlayerState::STOP:
|
||||||
state = "stop";
|
state = "stop";
|
||||||
break;
|
break;
|
||||||
case PLAYER_STATE_PAUSE:
|
case PlayerState::PAUSE:
|
||||||
state = "pause";
|
state = "pause";
|
||||||
break;
|
break;
|
||||||
case PLAYER_STATE_PLAY:
|
case PlayerState::PLAY:
|
||||||
state = "play";
|
state = "play";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -168,7 +168,7 @@ handle_status(Client *client,
|
|||||||
song, playlist.PositionToId(song));
|
song, playlist.PositionToId(song));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (player_status.state != PLAYER_STATE_STOP) {
|
if (player_status.state != PlayerState::STOP) {
|
||||||
client_printf(client,
|
client_printf(client,
|
||||||
COMMAND_STATUS_TIME ": %i:%i\n"
|
COMMAND_STATUS_TIME ": %i:%i\n"
|
||||||
"elapsed: %1.3f\n"
|
"elapsed: %1.3f\n"
|
||||||
|
@ -32,9 +32,9 @@ player_control::player_control(unsigned _buffer_chunks,
|
|||||||
:buffer_chunks(_buffer_chunks),
|
:buffer_chunks(_buffer_chunks),
|
||||||
buffered_before_play(_buffered_before_play),
|
buffered_before_play(_buffered_before_play),
|
||||||
thread(nullptr),
|
thread(nullptr),
|
||||||
command(PLAYER_COMMAND_NONE),
|
command(PlayerCommand::NONE),
|
||||||
state(PLAYER_STATE_STOP),
|
state(PlayerState::STOP),
|
||||||
error_type(PLAYER_ERROR_NONE),
|
error_type(PlayerError::NONE),
|
||||||
next_song(nullptr),
|
next_song(nullptr),
|
||||||
cross_fade_seconds(0),
|
cross_fade_seconds(0),
|
||||||
mixramp_db(0),
|
mixramp_db(0),
|
||||||
@ -63,8 +63,8 @@ player_control::Play(Song *song)
|
|||||||
|
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
if (state != PLAYER_STATE_STOP)
|
if (state != PlayerState::STOP)
|
||||||
SynchronousCommand(PLAYER_COMMAND_STOP);
|
SynchronousCommand(PlayerCommand::STOP);
|
||||||
|
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
@ -78,14 +78,14 @@ player_control::Play(Song *song)
|
|||||||
void
|
void
|
||||||
player_control::Cancel()
|
player_control::Cancel()
|
||||||
{
|
{
|
||||||
LockSynchronousCommand(PLAYER_COMMAND_CANCEL);
|
LockSynchronousCommand(PlayerCommand::CANCEL);
|
||||||
assert(next_song == NULL);
|
assert(next_song == NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
player_control::Stop()
|
player_control::Stop()
|
||||||
{
|
{
|
||||||
LockSynchronousCommand(PLAYER_COMMAND_CLOSE_AUDIO);
|
LockSynchronousCommand(PlayerCommand::CLOSE_AUDIO);
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
@ -94,7 +94,7 @@ player_control::Stop()
|
|||||||
void
|
void
|
||||||
player_control::UpdateAudio()
|
player_control::UpdateAudio()
|
||||||
{
|
{
|
||||||
LockSynchronousCommand(PLAYER_COMMAND_UPDATE_AUDIO);
|
LockSynchronousCommand(PlayerCommand::UPDATE_AUDIO);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -102,7 +102,7 @@ player_control::Kill()
|
|||||||
{
|
{
|
||||||
assert(thread != NULL);
|
assert(thread != NULL);
|
||||||
|
|
||||||
LockSynchronousCommand(PLAYER_COMMAND_EXIT);
|
LockSynchronousCommand(PlayerCommand::EXIT);
|
||||||
g_thread_join(thread);
|
g_thread_join(thread);
|
||||||
thread = NULL;
|
thread = NULL;
|
||||||
|
|
||||||
@ -112,8 +112,8 @@ player_control::Kill()
|
|||||||
void
|
void
|
||||||
player_control::PauseLocked()
|
player_control::PauseLocked()
|
||||||
{
|
{
|
||||||
if (state != PLAYER_STATE_STOP) {
|
if (state != PlayerState::STOP) {
|
||||||
SynchronousCommand(PLAYER_COMMAND_PAUSE);
|
SynchronousCommand(PlayerCommand::PAUSE);
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -132,15 +132,15 @@ player_control::SetPause(bool pause_flag)
|
|||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case PLAYER_STATE_STOP:
|
case PlayerState::STOP:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_STATE_PLAY:
|
case PlayerState::PLAY:
|
||||||
if (pause_flag)
|
if (pause_flag)
|
||||||
PauseLocked();
|
PauseLocked();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_STATE_PAUSE:
|
case PlayerState::PAUSE:
|
||||||
if (!pause_flag)
|
if (!pause_flag)
|
||||||
PauseLocked();
|
PauseLocked();
|
||||||
break;
|
break;
|
||||||
@ -163,11 +163,11 @@ player_control::GetStatus()
|
|||||||
player_status status;
|
player_status status;
|
||||||
|
|
||||||
Lock();
|
Lock();
|
||||||
SynchronousCommand(PLAYER_COMMAND_REFRESH);
|
SynchronousCommand(PlayerCommand::REFRESH);
|
||||||
|
|
||||||
status.state = state;
|
status.state = state;
|
||||||
|
|
||||||
if (state != PLAYER_STATE_STOP) {
|
if (state != PlayerState::STOP) {
|
||||||
status.bit_rate = bit_rate;
|
status.bit_rate = bit_rate;
|
||||||
status.audio_format = audio_format;
|
status.audio_format = audio_format;
|
||||||
status.total_time = total_time;
|
status.total_time = total_time;
|
||||||
@ -180,9 +180,9 @@ player_control::GetStatus()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
player_control::SetError(player_error type, Error &&_error)
|
player_control::SetError(PlayerError type, Error &&_error)
|
||||||
{
|
{
|
||||||
assert(type != PLAYER_ERROR_NONE);
|
assert(type != PlayerError::NONE);
|
||||||
assert(_error.IsDefined());
|
assert(_error.IsDefined());
|
||||||
|
|
||||||
error_type = type;
|
error_type = type;
|
||||||
@ -194,8 +194,8 @@ player_control::ClearError()
|
|||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
|
|
||||||
if (error_type != PLAYER_ERROR_NONE) {
|
if (error_type != PlayerError::NONE) {
|
||||||
error_type = PLAYER_ERROR_NONE;
|
error_type = PlayerError::NONE;
|
||||||
error.Clear();
|
error.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ char *
|
|||||||
player_control::GetErrorMessage() const
|
player_control::GetErrorMessage() const
|
||||||
{
|
{
|
||||||
Lock();
|
Lock();
|
||||||
char *message = error_type != PLAYER_ERROR_NONE
|
char *message = error_type != PlayerError::NONE
|
||||||
? g_strdup(error.GetMessage())
|
? g_strdup(error.GetMessage())
|
||||||
: NULL;
|
: NULL;
|
||||||
Unlock();
|
Unlock();
|
||||||
@ -235,7 +235,7 @@ player_control::Seek(Song *song, float seek_time)
|
|||||||
|
|
||||||
next_song = song;
|
next_song = song;
|
||||||
seek_where = seek_time;
|
seek_where = seek_time;
|
||||||
SynchronousCommand(PLAYER_COMMAND_SEEK);
|
SynchronousCommand(PlayerCommand::SEEK);
|
||||||
Unlock();
|
Unlock();
|
||||||
|
|
||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
@ -29,62 +29,61 @@
|
|||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
struct decoder_control;
|
|
||||||
struct Song;
|
struct Song;
|
||||||
|
|
||||||
enum player_state {
|
enum class PlayerState : uint8_t {
|
||||||
PLAYER_STATE_STOP = 0,
|
STOP,
|
||||||
PLAYER_STATE_PAUSE,
|
PAUSE,
|
||||||
PLAYER_STATE_PLAY
|
PLAY
|
||||||
};
|
};
|
||||||
|
|
||||||
enum player_command {
|
enum class PlayerCommand : uint8_t {
|
||||||
PLAYER_COMMAND_NONE = 0,
|
NONE,
|
||||||
PLAYER_COMMAND_EXIT,
|
EXIT,
|
||||||
PLAYER_COMMAND_STOP,
|
STOP,
|
||||||
PLAYER_COMMAND_PAUSE,
|
PAUSE,
|
||||||
PLAYER_COMMAND_SEEK,
|
SEEK,
|
||||||
PLAYER_COMMAND_CLOSE_AUDIO,
|
CLOSE_AUDIO,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* At least one audio_output.enabled flag has been modified;
|
* At least one audio_output.enabled flag has been modified;
|
||||||
* commit those changes to the output threads.
|
* commit those changes to the output threads.
|
||||||
*/
|
*/
|
||||||
PLAYER_COMMAND_UPDATE_AUDIO,
|
UPDATE_AUDIO,
|
||||||
|
|
||||||
/** player_control.next_song has been updated */
|
/** player_control.next_song has been updated */
|
||||||
PLAYER_COMMAND_QUEUE,
|
QUEUE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* cancel pre-decoding player_control.next_song; if the player
|
* cancel pre-decoding player_control.next_song; if the player
|
||||||
* has already started playing this song, it will completely
|
* has already started playing this song, it will completely
|
||||||
* stop
|
* stop
|
||||||
*/
|
*/
|
||||||
PLAYER_COMMAND_CANCEL,
|
CANCEL,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Refresh status information in the #player_control struct,
|
* Refresh status information in the #player_control struct,
|
||||||
* e.g. elapsed_time.
|
* e.g. elapsed_time.
|
||||||
*/
|
*/
|
||||||
PLAYER_COMMAND_REFRESH,
|
REFRESH,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum player_error {
|
enum class PlayerError : uint8_t {
|
||||||
PLAYER_ERROR_NONE = 0,
|
NONE,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The decoder has failed to decode the song.
|
* The decoder has failed to decode the song.
|
||||||
*/
|
*/
|
||||||
PLAYER_ERROR_DECODER,
|
DECODER,
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The audio output has failed.
|
* The audio output has failed.
|
||||||
*/
|
*/
|
||||||
PLAYER_ERROR_OUTPUT,
|
OUTPUT,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct player_status {
|
struct player_status {
|
||||||
enum player_state state;
|
PlayerState state;
|
||||||
uint16_t bit_rate;
|
uint16_t bit_rate;
|
||||||
AudioFormat audio_format;
|
AudioFormat audio_format;
|
||||||
float total_time;
|
float total_time;
|
||||||
@ -117,16 +116,16 @@ struct player_control {
|
|||||||
*/
|
*/
|
||||||
Cond client_cond;
|
Cond client_cond;
|
||||||
|
|
||||||
enum player_command command;
|
PlayerCommand command;
|
||||||
enum player_state state;
|
PlayerState state;
|
||||||
|
|
||||||
enum player_error error_type;
|
PlayerError error_type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The error that occurred in the player thread. This
|
* The error that occurred in the player thread. This
|
||||||
* attribute is only valid if #error is not
|
* attribute is only valid if #error is not
|
||||||
* #PLAYER_ERROR_NONE. The object must be freed when this
|
* #PlayerError::NONE. The object must be freed when this
|
||||||
* object transitions back to #PLAYER_ERROR_NONE.
|
* object transitions back to #PlayerError::NONE.
|
||||||
*/
|
*/
|
||||||
Error error;
|
Error error;
|
||||||
|
|
||||||
@ -236,9 +235,9 @@ struct player_control {
|
|||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void CommandFinished() {
|
void CommandFinished() {
|
||||||
assert(command != PLAYER_COMMAND_NONE);
|
assert(command != PlayerCommand::NONE);
|
||||||
|
|
||||||
command = PLAYER_COMMAND_NONE;
|
command = PlayerCommand::NONE;
|
||||||
ClientSignal();
|
ClientSignal();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -250,7 +249,7 @@ private:
|
|||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void WaitCommandLocked() {
|
void WaitCommandLocked() {
|
||||||
while (command != PLAYER_COMMAND_NONE)
|
while (command != PlayerCommand::NONE)
|
||||||
ClientWait();
|
ClientWait();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,8 +260,8 @@ private:
|
|||||||
* To be called from the main thread. Caller must lock the
|
* To be called from the main thread. Caller must lock the
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void SynchronousCommand(player_command cmd) {
|
void SynchronousCommand(PlayerCommand cmd) {
|
||||||
assert(command == PLAYER_COMMAND_NONE);
|
assert(command == PlayerCommand::NONE);
|
||||||
|
|
||||||
command = cmd;
|
command = cmd;
|
||||||
Signal();
|
Signal();
|
||||||
@ -276,7 +275,7 @@ private:
|
|||||||
* To be called from the main thread. This method locks the
|
* To be called from the main thread. This method locks the
|
||||||
* object.
|
* object.
|
||||||
*/
|
*/
|
||||||
void LockSynchronousCommand(player_command cmd) {
|
void LockSynchronousCommand(PlayerCommand cmd) {
|
||||||
Lock();
|
Lock();
|
||||||
SynchronousCommand(cmd);
|
SynchronousCommand(cmd);
|
||||||
Unlock();
|
Unlock();
|
||||||
@ -290,7 +289,7 @@ public:
|
|||||||
void Play(Song *song);
|
void Play(Song *song);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* see PLAYER_COMMAND_CANCEL
|
* see PlayerCommand::CANCEL
|
||||||
*/
|
*/
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
@ -312,7 +311,7 @@ public:
|
|||||||
gcc_pure
|
gcc_pure
|
||||||
player_status GetStatus();
|
player_status GetStatus();
|
||||||
|
|
||||||
player_state GetState() const {
|
PlayerState GetState() const {
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -321,10 +320,10 @@ public:
|
|||||||
*
|
*
|
||||||
* Caller must lock the object.
|
* Caller must lock the object.
|
||||||
*
|
*
|
||||||
* @param type the error type; must not be #PLAYER_ERROR_NONE
|
* @param type the error type; must not be #PlayerError::NONE
|
||||||
* @param error detailed error information; must be defined.
|
* @param error detailed error information; must be defined.
|
||||||
*/
|
*/
|
||||||
void SetError(player_error type, Error &&error);
|
void SetError(PlayerError type, Error &&error);
|
||||||
|
|
||||||
void ClearError();
|
void ClearError();
|
||||||
|
|
||||||
@ -335,7 +334,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
char *GetErrorMessage() const;
|
char *GetErrorMessage() const;
|
||||||
|
|
||||||
player_error GetErrorType() const {
|
PlayerError GetErrorType() const {
|
||||||
return error_type;
|
return error_type;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -349,7 +348,7 @@ private:
|
|||||||
assert(next_song == nullptr);
|
assert(next_song == nullptr);
|
||||||
|
|
||||||
next_song = song;
|
next_song = song;
|
||||||
SynchronousCommand(PLAYER_COMMAND_QUEUE);
|
SynchronousCommand(PlayerCommand::QUEUE);
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -205,7 +205,7 @@ struct player {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the handler for the #PLAYER_COMMAND_SEEK command.
|
* This is the handler for the #PlayerCommand::SEEK command.
|
||||||
*
|
*
|
||||||
* The player lock is not held.
|
* The player lock is not held.
|
||||||
*/
|
*/
|
||||||
@ -281,11 +281,11 @@ player_command_finished(player_control &pc)
|
|||||||
void
|
void
|
||||||
player::StartDecoder(MusicPipe &_pipe)
|
player::StartDecoder(MusicPipe &_pipe)
|
||||||
{
|
{
|
||||||
assert(queued || pc.command == PLAYER_COMMAND_SEEK);
|
assert(queued || pc.command == PlayerCommand::SEEK);
|
||||||
assert(pc.next_song != nullptr);
|
assert(pc.next_song != nullptr);
|
||||||
|
|
||||||
unsigned start_ms = pc.next_song->start_ms;
|
unsigned start_ms = pc.next_song->start_ms;
|
||||||
if (pc.command == PLAYER_COMMAND_SEEK)
|
if (pc.command == PlayerCommand::SEEK)
|
||||||
start_ms += (unsigned)(pc.seek_where * 1000);
|
start_ms += (unsigned)(pc.seek_where * 1000);
|
||||||
|
|
||||||
dc.Start(pc.next_song->DupDetached(),
|
dc.Start(pc.next_song->DupDetached(),
|
||||||
@ -313,7 +313,7 @@ player::StopDecoder()
|
|||||||
bool
|
bool
|
||||||
player::WaitForDecoder()
|
player::WaitForDecoder()
|
||||||
{
|
{
|
||||||
assert(queued || pc.command == PLAYER_COMMAND_SEEK);
|
assert(queued || pc.command == PlayerCommand::SEEK);
|
||||||
assert(pc.next_song != nullptr);
|
assert(pc.next_song != nullptr);
|
||||||
|
|
||||||
queued = false;
|
queued = false;
|
||||||
@ -321,7 +321,7 @@ player::WaitForDecoder()
|
|||||||
Error error = dc.LockGetError();
|
Error error = dc.LockGetError();
|
||||||
if (error.IsDefined()) {
|
if (error.IsDefined()) {
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.SetError(PLAYER_ERROR_DECODER, std::move(error));
|
pc.SetError(PlayerError::DECODER, std::move(error));
|
||||||
|
|
||||||
pc.next_song->Free();
|
pc.next_song->Free();
|
||||||
pc.next_song = nullptr;
|
pc.next_song = nullptr;
|
||||||
@ -383,8 +383,8 @@ bool
|
|||||||
player::OpenOutput()
|
player::OpenOutput()
|
||||||
{
|
{
|
||||||
assert(play_audio_format.IsDefined());
|
assert(play_audio_format.IsDefined());
|
||||||
assert(pc.state == PLAYER_STATE_PLAY ||
|
assert(pc.state == PlayerState::PLAY ||
|
||||||
pc.state == PLAYER_STATE_PAUSE);
|
pc.state == PlayerState::PAUSE);
|
||||||
|
|
||||||
Error error;
|
Error error;
|
||||||
if (audio_output_all_open(play_audio_format, buffer, error)) {
|
if (audio_output_all_open(play_audio_format, buffer, error)) {
|
||||||
@ -392,7 +392,7 @@ player::OpenOutput()
|
|||||||
paused = false;
|
paused = false;
|
||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.state = PLAYER_STATE_PLAY;
|
pc.state = PlayerState::PLAY;
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
@ -408,8 +408,8 @@ player::OpenOutput()
|
|||||||
paused = true;
|
paused = true;
|
||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.SetError(PLAYER_ERROR_OUTPUT, std::move(error));
|
pc.SetError(PlayerError::OUTPUT, std::move(error));
|
||||||
pc.state = PLAYER_STATE_PAUSE;
|
pc.state = PlayerState::PAUSE;
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
idle_add(IDLE_PLAYER);
|
idle_add(IDLE_PLAYER);
|
||||||
@ -431,7 +431,7 @@ player::CheckDecoderStartup()
|
|||||||
dc.Unlock();
|
dc.Unlock();
|
||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.SetError(PLAYER_ERROR_DECODER, std::move(error));
|
pc.SetError(PlayerError::DECODER, std::move(error));
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -589,20 +589,20 @@ inline void
|
|||||||
player::ProcessCommand()
|
player::ProcessCommand()
|
||||||
{
|
{
|
||||||
switch (pc.command) {
|
switch (pc.command) {
|
||||||
case PLAYER_COMMAND_NONE:
|
case PlayerCommand::NONE:
|
||||||
case PLAYER_COMMAND_STOP:
|
case PlayerCommand::STOP:
|
||||||
case PLAYER_COMMAND_EXIT:
|
case PlayerCommand::EXIT:
|
||||||
case PLAYER_COMMAND_CLOSE_AUDIO:
|
case PlayerCommand::CLOSE_AUDIO:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_UPDATE_AUDIO:
|
case PlayerCommand::UPDATE_AUDIO:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
audio_output_all_enable_disable();
|
audio_output_all_enable_disable();
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_QUEUE:
|
case PlayerCommand::QUEUE:
|
||||||
assert(pc.next_song != nullptr);
|
assert(pc.next_song != nullptr);
|
||||||
assert(!queued);
|
assert(!queued);
|
||||||
assert(!IsDecoderAtNextSong());
|
assert(!IsDecoderAtNextSong());
|
||||||
@ -611,7 +611,7 @@ player::ProcessCommand()
|
|||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_PAUSE:
|
case PlayerCommand::PAUSE:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
paused = !paused;
|
paused = !paused;
|
||||||
@ -619,13 +619,13 @@ player::ProcessCommand()
|
|||||||
audio_output_all_pause();
|
audio_output_all_pause();
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
|
|
||||||
pc.state = PLAYER_STATE_PAUSE;
|
pc.state = PlayerState::PAUSE;
|
||||||
} else if (!play_audio_format.IsDefined()) {
|
} else if (!play_audio_format.IsDefined()) {
|
||||||
/* the decoder hasn't provided an audio format
|
/* the decoder hasn't provided an audio format
|
||||||
yet - don't open the audio device yet */
|
yet - don't open the audio device yet */
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
|
|
||||||
pc.state = PLAYER_STATE_PLAY;
|
pc.state = PlayerState::PLAY;
|
||||||
} else {
|
} else {
|
||||||
OpenOutput();
|
OpenOutput();
|
||||||
|
|
||||||
@ -635,18 +635,18 @@ player::ProcessCommand()
|
|||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_SEEK:
|
case PlayerCommand::SEEK:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
SeekDecoder();
|
SeekDecoder();
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_CANCEL:
|
case PlayerCommand::CANCEL:
|
||||||
if (pc.next_song == nullptr) {
|
if (pc.next_song == nullptr) {
|
||||||
/* the cancel request arrived too late, we're
|
/* the cancel request arrived too late, we're
|
||||||
already playing the queued song... stop
|
already playing the queued song... stop
|
||||||
everything now */
|
everything now */
|
||||||
pc.command = PLAYER_COMMAND_STOP;
|
pc.command = PlayerCommand::STOP;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -664,7 +664,7 @@ player::ProcessCommand()
|
|||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_REFRESH:
|
case PlayerCommand::REFRESH:
|
||||||
if (output_open && !paused) {
|
if (output_open && !paused) {
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
audio_output_all_check();
|
audio_output_all_check();
|
||||||
@ -841,11 +841,11 @@ player::PlayNextChunk()
|
|||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
|
|
||||||
pc.SetError(PLAYER_ERROR_OUTPUT, std::move(error));
|
pc.SetError(PlayerError::OUTPUT, std::move(error));
|
||||||
|
|
||||||
/* pause: the user may resume playback as soon as an
|
/* pause: the user may resume playback as soon as an
|
||||||
audio output becomes available */
|
audio output becomes available */
|
||||||
pc.state = PLAYER_STATE_PAUSE;
|
pc.state = PlayerState::PAUSE;
|
||||||
paused = true;
|
paused = true;
|
||||||
|
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
@ -889,7 +889,7 @@ player::SongBorder()
|
|||||||
const bool border_pause = pc.border_pause;
|
const bool border_pause = pc.border_pause;
|
||||||
if (border_pause) {
|
if (border_pause) {
|
||||||
paused = true;
|
paused = true;
|
||||||
pc.state = PLAYER_STATE_PAUSE;
|
pc.state = PlayerState::PAUSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
@ -916,18 +916,18 @@ player::Run()
|
|||||||
}
|
}
|
||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.state = PLAYER_STATE_PLAY;
|
pc.state = PlayerState::PLAY;
|
||||||
|
|
||||||
if (pc.command == PLAYER_COMMAND_SEEK)
|
if (pc.command == PlayerCommand::SEEK)
|
||||||
elapsed_time = pc.seek_where;
|
elapsed_time = pc.seek_where;
|
||||||
|
|
||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ProcessCommand();
|
ProcessCommand();
|
||||||
if (pc.command == PLAYER_COMMAND_STOP ||
|
if (pc.command == PlayerCommand::STOP ||
|
||||||
pc.command == PLAYER_COMMAND_EXIT ||
|
pc.command == PlayerCommand::EXIT ||
|
||||||
pc.command == PLAYER_COMMAND_CLOSE_AUDIO) {
|
pc.command == PlayerCommand::CLOSE_AUDIO) {
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
audio_output_all_cancel();
|
audio_output_all_cancel();
|
||||||
break;
|
break;
|
||||||
@ -1021,7 +1021,7 @@ player::Run()
|
|||||||
if (paused) {
|
if (paused) {
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
|
|
||||||
if (pc.command == PLAYER_COMMAND_NONE)
|
if (pc.command == PlayerCommand::NONE)
|
||||||
pc.Wait();
|
pc.Wait();
|
||||||
continue;
|
continue;
|
||||||
} else if (!pipe->IsEmpty()) {
|
} else if (!pipe->IsEmpty()) {
|
||||||
@ -1079,7 +1079,7 @@ player::Run()
|
|||||||
pc.next_song = nullptr;
|
pc.next_song = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
pc.state = PLAYER_STATE_STOP;
|
pc.state = PlayerState::STOP;
|
||||||
|
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
}
|
}
|
||||||
@ -1106,8 +1106,8 @@ player_task(gpointer arg)
|
|||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
switch (pc.command) {
|
switch (pc.command) {
|
||||||
case PLAYER_COMMAND_SEEK:
|
case PlayerCommand::SEEK:
|
||||||
case PLAYER_COMMAND_QUEUE:
|
case PlayerCommand::QUEUE:
|
||||||
assert(pc.next_song != nullptr);
|
assert(pc.next_song != nullptr);
|
||||||
|
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
@ -1116,14 +1116,14 @@ player_task(gpointer arg)
|
|||||||
pc.Lock();
|
pc.Lock();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_STOP:
|
case PlayerCommand::STOP:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
audio_output_all_cancel();
|
audio_output_all_cancel();
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
|
|
||||||
/* fall through */
|
/* fall through */
|
||||||
|
|
||||||
case PLAYER_COMMAND_PAUSE:
|
case PlayerCommand::PAUSE:
|
||||||
if (pc.next_song != nullptr) {
|
if (pc.next_song != nullptr) {
|
||||||
pc.next_song->Free();
|
pc.next_song->Free();
|
||||||
pc.next_song = nullptr;
|
pc.next_song = nullptr;
|
||||||
@ -1132,7 +1132,7 @@ player_task(gpointer arg)
|
|||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_CLOSE_AUDIO:
|
case PlayerCommand::CLOSE_AUDIO:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
audio_output_all_release();
|
audio_output_all_release();
|
||||||
@ -1144,14 +1144,14 @@ player_task(gpointer arg)
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_UPDATE_AUDIO:
|
case PlayerCommand::UPDATE_AUDIO:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
audio_output_all_enable_disable();
|
audio_output_all_enable_disable();
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_EXIT:
|
case PlayerCommand::EXIT:
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
dc.Quit();
|
dc.Quit();
|
||||||
@ -1161,7 +1161,7 @@ player_task(gpointer arg)
|
|||||||
player_command_finished(pc);
|
player_command_finished(pc);
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
case PLAYER_COMMAND_CANCEL:
|
case PlayerCommand::CANCEL:
|
||||||
if (pc.next_song != nullptr) {
|
if (pc.next_song != nullptr) {
|
||||||
pc.next_song->Free();
|
pc.next_song->Free();
|
||||||
pc.next_song = nullptr;
|
pc.next_song = nullptr;
|
||||||
@ -1170,12 +1170,12 @@ player_task(gpointer arg)
|
|||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_REFRESH:
|
case PlayerCommand::REFRESH:
|
||||||
/* no-op when not playing */
|
/* no-op when not playing */
|
||||||
pc.CommandFinished();
|
pc.CommandFinished();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PLAYER_COMMAND_NONE:
|
case PlayerCommand::NONE:
|
||||||
pc.Wait();
|
pc.Wait();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -175,11 +175,11 @@ playlist::SyncWithPlayer(player_control &pc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
pc.Lock();
|
pc.Lock();
|
||||||
const player_state pc_state = pc.GetState();
|
const PlayerState pc_state = pc.GetState();
|
||||||
const Song *pc_next_song = pc.next_song;
|
const Song *pc_next_song = pc.next_song;
|
||||||
pc.Unlock();
|
pc.Unlock();
|
||||||
|
|
||||||
if (pc_state == PLAYER_STATE_STOP)
|
if (pc_state == PlayerState::STOP)
|
||||||
/* the player thread has stopped: check if playback
|
/* the player thread has stopped: check if playback
|
||||||
should be restarted with the next song. That can
|
should be restarted with the next song. That can
|
||||||
happen if the playlist isn't filling the queue fast
|
happen if the playlist isn't filling the queue fast
|
||||||
@ -210,16 +210,16 @@ static void
|
|||||||
playlist_resume_playback(struct playlist *playlist, struct player_control *pc)
|
playlist_resume_playback(struct playlist *playlist, struct player_control *pc)
|
||||||
{
|
{
|
||||||
assert(playlist->playing);
|
assert(playlist->playing);
|
||||||
assert(pc->GetState() == PLAYER_STATE_STOP);
|
assert(pc->GetState() == PlayerState::STOP);
|
||||||
|
|
||||||
const auto error = pc->GetErrorType();
|
const auto error = pc->GetErrorType();
|
||||||
if (error == PLAYER_ERROR_NONE)
|
if (error == PlayerError::NONE)
|
||||||
playlist->error_count = 0;
|
playlist->error_count = 0;
|
||||||
else
|
else
|
||||||
++playlist->error_count;
|
++playlist->error_count;
|
||||||
|
|
||||||
if ((playlist->stop_on_error && error != PLAYER_ERROR_NONE) ||
|
if ((playlist->stop_on_error && error != PlayerError::NONE) ||
|
||||||
error == PLAYER_ERROR_OUTPUT ||
|
error == PlayerError::OUTPUT ||
|
||||||
playlist->error_count >= playlist->queue.GetLength())
|
playlist->error_count >= playlist->queue.GetLength())
|
||||||
/* too many errors, or critical error: stop
|
/* too many errors, or critical error: stop
|
||||||
playback */
|
playback */
|
||||||
|
@ -250,8 +250,8 @@ playlist::SeekCurrent(player_control &pc, float seek_time, bool relative)
|
|||||||
if (relative) {
|
if (relative) {
|
||||||
const auto status = pc.GetStatus();
|
const auto status = pc.GetStatus();
|
||||||
|
|
||||||
if (status.state != PLAYER_STATE_PLAY &&
|
if (status.state != PlayerState::PLAY &&
|
||||||
status.state != PLAYER_STATE_PAUSE)
|
status.state != PlayerState::PAUSE)
|
||||||
return PLAYLIST_RESULT_NOT_PLAYING;
|
return PLAYLIST_RESULT_NOT_PLAYING;
|
||||||
|
|
||||||
seek_time += (int)status.elapsed_time;
|
seek_time += (int)status.elapsed_time;
|
||||||
|
@ -226,7 +226,7 @@ playlist::DeleteInternal(player_control &pc,
|
|||||||
unsigned songOrder = queue.PositionToOrder(song);
|
unsigned songOrder = queue.PositionToOrder(song);
|
||||||
|
|
||||||
if (playing && current == (int)songOrder) {
|
if (playing && current == (int)songOrder) {
|
||||||
const bool paused = pc.GetState() == PLAYER_STATE_PAUSE;
|
const bool paused = pc.GetState() == PlayerState::PAUSE;
|
||||||
|
|
||||||
/* the current song is going to be deleted: stop the player */
|
/* the current song is going to be deleted: stop the player */
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ playlist_state_save(FILE *fp, const struct playlist *playlist,
|
|||||||
|
|
||||||
if (playlist->playing) {
|
if (playlist->playing) {
|
||||||
switch (player_status.state) {
|
switch (player_status.state) {
|
||||||
case PLAYER_STATE_PAUSE:
|
case PlayerState::PAUSE:
|
||||||
fputs(PLAYLIST_STATE_FILE_STATE_PAUSE "\n", fp);
|
fputs(PLAYLIST_STATE_FILE_STATE_PAUSE "\n", fp);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -126,7 +126,6 @@ playlist_state_restore(const char *line, TextFile &file,
|
|||||||
{
|
{
|
||||||
int current = -1;
|
int current = -1;
|
||||||
int seek_time = 0;
|
int seek_time = 0;
|
||||||
enum player_state state = PLAYER_STATE_STOP;
|
|
||||||
bool random_mode = false;
|
bool random_mode = false;
|
||||||
|
|
||||||
if (!g_str_has_prefix(line, PLAYLIST_STATE_FILE_STATE))
|
if (!g_str_has_prefix(line, PLAYLIST_STATE_FILE_STATE))
|
||||||
@ -134,10 +133,13 @@ playlist_state_restore(const char *line, TextFile &file,
|
|||||||
|
|
||||||
line += sizeof(PLAYLIST_STATE_FILE_STATE) - 1;
|
line += sizeof(PLAYLIST_STATE_FILE_STATE) - 1;
|
||||||
|
|
||||||
|
PlayerState state;
|
||||||
if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PLAY) == 0)
|
if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PLAY) == 0)
|
||||||
state = PLAYER_STATE_PLAY;
|
state = PlayerState::PLAY;
|
||||||
else if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PAUSE) == 0)
|
else if (strcmp(line, PLAYLIST_STATE_FILE_STATE_PAUSE) == 0)
|
||||||
state = PLAYER_STATE_PAUSE;
|
state = PlayerState::PAUSE;
|
||||||
|
else
|
||||||
|
state = PlayerState::STOP;
|
||||||
|
|
||||||
while ((line = file.ReadLine()) != NULL) {
|
while ((line = file.ReadLine()) != NULL) {
|
||||||
if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_TIME)) {
|
if (g_str_has_prefix(line, PLAYLIST_STATE_FILE_TIME)) {
|
||||||
@ -180,27 +182,27 @@ playlist_state_restore(const char *line, TextFile &file,
|
|||||||
if (!playlist->queue.IsValidPosition(current))
|
if (!playlist->queue.IsValidPosition(current))
|
||||||
current = 0;
|
current = 0;
|
||||||
|
|
||||||
if (state == PLAYER_STATE_PLAY &&
|
if (state == PlayerState::PLAY &&
|
||||||
config_get_bool(CONF_RESTORE_PAUSED, false))
|
config_get_bool(CONF_RESTORE_PAUSED, false))
|
||||||
/* the user doesn't want MPD to auto-start
|
/* the user doesn't want MPD to auto-start
|
||||||
playback after startup; fall back to
|
playback after startup; fall back to
|
||||||
"pause" */
|
"pause" */
|
||||||
state = PLAYER_STATE_PAUSE;
|
state = PlayerState::PAUSE;
|
||||||
|
|
||||||
/* enable all devices for the first time; this must be
|
/* enable all devices for the first time; this must be
|
||||||
called here, after the audio output states were
|
called here, after the audio output states were
|
||||||
restored, before playback begins */
|
restored, before playback begins */
|
||||||
if (state != PLAYER_STATE_STOP)
|
if (state != PlayerState::STOP)
|
||||||
pc->UpdateAudio();
|
pc->UpdateAudio();
|
||||||
|
|
||||||
if (state == PLAYER_STATE_STOP /* && config_option */)
|
if (state == PlayerState::STOP /* && config_option */)
|
||||||
playlist->current = current;
|
playlist->current = current;
|
||||||
else if (seek_time == 0)
|
else if (seek_time == 0)
|
||||||
playlist->PlayPosition(*pc, current);
|
playlist->PlayPosition(*pc, current);
|
||||||
else
|
else
|
||||||
playlist->SeekSongPosition(*pc, current, seek_time);
|
playlist->SeekSongPosition(*pc, current, seek_time);
|
||||||
|
|
||||||
if (state == PLAYER_STATE_PAUSE)
|
if (state == PlayerState::PAUSE)
|
||||||
pc->Pause();
|
pc->Pause();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -214,14 +216,14 @@ playlist_state_get_hash(const struct playlist *playlist,
|
|||||||
const auto player_status = pc->GetStatus();
|
const auto player_status = pc->GetStatus();
|
||||||
|
|
||||||
return playlist->queue.version ^
|
return playlist->queue.version ^
|
||||||
(player_status.state != PLAYER_STATE_STOP
|
(player_status.state != PlayerState::STOP
|
||||||
? ((int)player_status.elapsed_time << 8)
|
? ((int)player_status.elapsed_time << 8)
|
||||||
: 0) ^
|
: 0) ^
|
||||||
(playlist->current >= 0
|
(playlist->current >= 0
|
||||||
? (playlist->queue.OrderToPosition(playlist->current) << 16)
|
? (playlist->queue.OrderToPosition(playlist->current) << 16)
|
||||||
: 0) ^
|
: 0) ^
|
||||||
((int)pc->GetCrossFade() << 20) ^
|
((int)pc->GetCrossFade() << 20) ^
|
||||||
(player_status.state << 24) ^
|
(unsigned(player_status.state) << 24) ^
|
||||||
(playlist->queue.random << 27) ^
|
(playlist->queue.random << 27) ^
|
||||||
(playlist->queue.repeat << 28) ^
|
(playlist->queue.repeat << 28) ^
|
||||||
(playlist->queue.single << 29) ^
|
(playlist->queue.single << 29) ^
|
||||||
|
Loading…
Reference in New Issue
Block a user