output/Internal: convert audio_output_command to strictly-typed enum

This commit is contained in:
Max Kellermann 2014-12-24 22:13:50 +01:00
parent 2ea633a2f7
commit 54fc8f0e8c
4 changed files with 49 additions and 47 deletions

View File

@ -58,7 +58,7 @@ AudioOutput::AudioOutput(const AudioOutputPlugin &_plugin)
filter(nullptr), filter(nullptr),
replay_gain_filter(nullptr), replay_gain_filter(nullptr),
other_replay_gain_filter(nullptr), other_replay_gain_filter(nullptr),
command(AO_COMMAND_NONE) command(AudioOutputCommand::NONE)
{ {
assert(plugin.finish != nullptr); assert(plugin.finish != nullptr);
assert(plugin.open != nullptr); assert(plugin.open != nullptr);

View File

@ -40,29 +40,29 @@ struct config_param;
struct PlayerControl; struct PlayerControl;
struct AudioOutputPlugin; struct AudioOutputPlugin;
enum audio_output_command { enum class AudioOutputCommand {
AO_COMMAND_NONE = 0, NONE,
AO_COMMAND_ENABLE, ENABLE,
AO_COMMAND_DISABLE, DISABLE,
AO_COMMAND_OPEN, OPEN,
/** /**
* This command is invoked when the input audio format * This command is invoked when the input audio format
* changes. * changes.
*/ */
AO_COMMAND_REOPEN, REOPEN,
AO_COMMAND_CLOSE, CLOSE,
AO_COMMAND_PAUSE, PAUSE,
/** /**
* Drains the internal (hardware) buffers of the device. This * Drains the internal (hardware) buffers of the device. This
* operation may take a while to complete. * operation may take a while to complete.
*/ */
AO_COMMAND_DRAIN, DRAIN,
AO_COMMAND_CANCEL, CANCEL,
AO_COMMAND_KILL KILL
}; };
struct AudioOutput { struct AudioOutput {
@ -231,7 +231,7 @@ struct AudioOutput {
/** /**
* The next command to be performed by the output thread. * The next command to be performed by the output thread.
*/ */
enum audio_output_command command; AudioOutputCommand command;
/** /**
* The music pipe which provides music chunks to be played. * The music pipe which provides music chunks to be played.
@ -284,7 +284,7 @@ struct AudioOutput {
} }
bool IsCommandFinished() const { bool IsCommandFinished() const {
return command == AO_COMMAND_NONE; return command == AudioOutputCommand::NONE;
} }
/** /**
@ -299,7 +299,7 @@ struct AudioOutput {
* *
* Caller must lock the mutex. * Caller must lock the mutex.
*/ */
void CommandAsync(audio_output_command cmd); void CommandAsync(AudioOutputCommand cmd);
/** /**
* Sends a command to the #AudioOutput object and waits for * Sends a command to the #AudioOutput object and waits for
@ -307,13 +307,13 @@ struct AudioOutput {
* *
* Caller must lock the mutex. * Caller must lock the mutex.
*/ */
void CommandWait(audio_output_command cmd); void CommandWait(AudioOutputCommand cmd);
/** /**
* Lock the #AudioOutput object and execute the command * Lock the #AudioOutput object and execute the command
* synchronously. * synchronously.
*/ */
void LockCommandWait(audio_output_command cmd); void LockCommandWait(AudioOutputCommand cmd);
/** /**
* Enables the device. * Enables the device.

View File

@ -46,7 +46,7 @@ AudioOutput::WaitForCommand()
} }
void void
AudioOutput::CommandAsync(audio_output_command cmd) AudioOutput::CommandAsync(AudioOutputCommand cmd)
{ {
assert(IsCommandFinished()); assert(IsCommandFinished());
@ -55,14 +55,14 @@ AudioOutput::CommandAsync(audio_output_command cmd)
} }
void void
AudioOutput::CommandWait(audio_output_command cmd) AudioOutput::CommandWait(AudioOutputCommand cmd)
{ {
CommandAsync(cmd); CommandAsync(cmd);
WaitForCommand(); WaitForCommand();
} }
void void
AudioOutput::LockCommandWait(audio_output_command cmd) AudioOutput::LockCommandWait(AudioOutputCommand cmd)
{ {
const ScopeLock protect(mutex); const ScopeLock protect(mutex);
CommandWait(cmd); CommandWait(cmd);
@ -92,7 +92,7 @@ AudioOutput::LockEnableWait()
StartThread(); StartThread();
} }
LockCommandWait(AO_COMMAND_ENABLE); LockCommandWait(AudioOutputCommand::ENABLE);
} }
void void
@ -109,7 +109,7 @@ AudioOutput::LockDisableWait()
return; return;
} }
LockCommandWait(AO_COMMAND_DISABLE); LockCommandWait(AudioOutputCommand::DISABLE);
} }
inline bool inline bool
@ -134,7 +134,7 @@ AudioOutput::Open(const AudioFormat audio_format, const MusicPipe &mp)
/* we're not using audio_output_cancel() here, /* we're not using audio_output_cancel() here,
because that function is asynchronous */ because that function is asynchronous */
CommandWait(AO_COMMAND_CANCEL); CommandWait(AudioOutputCommand::CANCEL);
} }
return true; return true;
@ -148,7 +148,9 @@ AudioOutput::Open(const AudioFormat audio_format, const MusicPipe &mp)
if (!thread.IsDefined()) if (!thread.IsDefined())
StartThread(); StartThread();
CommandWait(open ? AO_COMMAND_REOPEN : AO_COMMAND_OPEN); CommandWait(open
? AudioOutputCommand::REOPEN
: AudioOutputCommand::OPEN);
const bool open2 = open; const bool open2 = open;
if (open2 && mixer != nullptr) { if (open2 && mixer != nullptr) {
@ -172,7 +174,7 @@ AudioOutput::CloseWait()
assert(!open || !fail_timer.IsDefined()); assert(!open || !fail_timer.IsDefined());
if (open) if (open)
CommandWait(AO_COMMAND_CLOSE); CommandWait(AudioOutputCommand::CLOSE);
else else
fail_timer.Reset(); fail_timer.Reset();
} }
@ -219,7 +221,7 @@ AudioOutput::LockPauseAsync()
assert(allow_play); assert(allow_play);
if (IsOpen()) if (IsOpen())
CommandAsync(AO_COMMAND_PAUSE); CommandAsync(AudioOutputCommand::PAUSE);
} }
void void
@ -229,7 +231,7 @@ AudioOutput::LockDrainAsync()
assert(allow_play); assert(allow_play);
if (IsOpen()) if (IsOpen())
CommandAsync(AO_COMMAND_DRAIN); CommandAsync(AudioOutputCommand::DRAIN);
} }
void void
@ -239,7 +241,7 @@ AudioOutput::LockCancelAsync()
if (IsOpen()) { if (IsOpen()) {
allow_play = false; allow_play = false;
CommandAsync(AO_COMMAND_CANCEL); CommandAsync(AudioOutputCommand::CANCEL);
} }
} }
@ -277,7 +279,7 @@ AudioOutput::StopThread()
assert(thread.IsDefined()); assert(thread.IsDefined());
assert(allow_play); assert(allow_play);
LockCommandWait(AO_COMMAND_KILL); LockCommandWait(AudioOutputCommand::KILL);
thread.Join(); thread.Join();
} }

View File

@ -45,8 +45,8 @@
void void
AudioOutput::CommandFinished() AudioOutput::CommandFinished()
{ {
assert(command != AO_COMMAND_NONE); assert(command != AudioOutputCommand::NONE);
command = AO_COMMAND_NONE; command = AudioOutputCommand::NONE;
mutex.unlock(); mutex.unlock();
audio_output_client_notify.Signal(); audio_output_client_notify.Signal();
@ -342,7 +342,7 @@ AudioOutput::WaitForDelay()
(void)cond.timed_wait(mutex, delay); (void)cond.timed_wait(mutex, delay);
if (command != AO_COMMAND_NONE) if (command != AudioOutputCommand::NONE)
return false; return false;
} }
} }
@ -471,7 +471,7 @@ AudioOutput::PlayChunk(const MusicChunk *chunk)
Error error; Error error;
while (!data.IsEmpty() && command == AO_COMMAND_NONE) { while (!data.IsEmpty() && command == AudioOutputCommand::NONE) {
if (!WaitForDelay()) if (!WaitForDelay())
break; break;
@ -529,7 +529,7 @@ AudioOutput::Play()
assert(!in_playback_loop); assert(!in_playback_loop);
in_playback_loop = true; in_playback_loop = true;
while (chunk != nullptr && command == AO_COMMAND_NONE) { while (chunk != nullptr && command == AudioOutputCommand::NONE) {
assert(!current_chunk_finished); assert(!current_chunk_finished);
current_chunk = chunk; current_chunk = chunk;
@ -577,7 +577,7 @@ AudioOutput::Pause()
Close(false); Close(false);
break; break;
} }
} while (command == AO_COMMAND_NONE); } while (command == AudioOutputCommand::NONE);
pause = false; pause = false;
} }
@ -594,30 +594,30 @@ AudioOutput::Task()
while (1) { while (1) {
switch (command) { switch (command) {
case AO_COMMAND_NONE: case AudioOutputCommand::NONE:
break; break;
case AO_COMMAND_ENABLE: case AudioOutputCommand::ENABLE:
Enable(); Enable();
CommandFinished(); CommandFinished();
break; break;
case AO_COMMAND_DISABLE: case AudioOutputCommand::DISABLE:
Disable(); Disable();
CommandFinished(); CommandFinished();
break; break;
case AO_COMMAND_OPEN: case AudioOutputCommand::OPEN:
Open(); Open();
CommandFinished(); CommandFinished();
break; break;
case AO_COMMAND_REOPEN: case AudioOutputCommand::REOPEN:
Reopen(); Reopen();
CommandFinished(); CommandFinished();
break; break;
case AO_COMMAND_CLOSE: case AudioOutputCommand::CLOSE:
assert(open); assert(open);
assert(pipe != nullptr); assert(pipe != nullptr);
@ -625,7 +625,7 @@ AudioOutput::Task()
CommandFinished(); CommandFinished();
break; break;
case AO_COMMAND_PAUSE: case AudioOutputCommand::PAUSE:
if (!open) { if (!open) {
/* the output has failed after /* the output has failed after
audio_output_all_pause() has audio_output_all_pause() has
@ -642,7 +642,7 @@ AudioOutput::Task()
the new command first */ the new command first */
continue; continue;
case AO_COMMAND_DRAIN: case AudioOutputCommand::DRAIN:
if (open) { if (open) {
assert(current_chunk == nullptr); assert(current_chunk == nullptr);
assert(pipe->Peek() == nullptr); assert(pipe->Peek() == nullptr);
@ -655,7 +655,7 @@ AudioOutput::Task()
CommandFinished(); CommandFinished();
continue; continue;
case AO_COMMAND_CANCEL: case AudioOutputCommand::CANCEL:
current_chunk = nullptr; current_chunk = nullptr;
if (open) { if (open) {
@ -667,7 +667,7 @@ AudioOutput::Task()
CommandFinished(); CommandFinished();
continue; continue;
case AO_COMMAND_KILL: case AudioOutputCommand::KILL:
current_chunk = nullptr; current_chunk = nullptr;
CommandFinished(); CommandFinished();
mutex.unlock(); mutex.unlock();
@ -679,7 +679,7 @@ AudioOutput::Task()
chunks in the pipe */ chunks in the pipe */
continue; continue;
if (command == AO_COMMAND_NONE) { if (command == AudioOutputCommand::NONE) {
woken_for_play = false; woken_for_play = false;
cond.wait(mutex); cond.wait(mutex);
} }
@ -696,7 +696,7 @@ AudioOutput::Task(void *arg)
void void
AudioOutput::StartThread() AudioOutput::StartThread()
{ {
assert(command == AO_COMMAND_NONE); assert(command == AudioOutputCommand::NONE);
Error error; Error error;
if (!thread.Start(Task, this, error)) if (!thread.Start(Task, this, error))