output/Multiple: migrate from class Error to C++ exceptions
This commit is contained in:
parent
98a12c49dd
commit
445e82be75
@ -58,14 +58,8 @@ try {
|
||||
AudioOutput *output = audio_output_new(event_loop, block,
|
||||
mixer_listener,
|
||||
pc, error);
|
||||
if (output == nullptr) {
|
||||
if (block.line > 0)
|
||||
FormatFatalError("line %i: %s",
|
||||
block.line,
|
||||
error.GetMessage());
|
||||
else
|
||||
FatalError(error);
|
||||
}
|
||||
if (output == nullptr)
|
||||
throw std::runtime_error(error.GetMessage());
|
||||
|
||||
return output;
|
||||
} catch (const std::runtime_error &e) {
|
||||
@ -192,32 +186,27 @@ MultipleOutputs::SetReplayGainMode(ReplayGainMode mode)
|
||||
ao->SetReplayGainMode(mode);
|
||||
}
|
||||
|
||||
bool
|
||||
MultipleOutputs::Play(MusicChunk *chunk, Error &error)
|
||||
void
|
||||
MultipleOutputs::Play(MusicChunk *chunk)
|
||||
{
|
||||
assert(buffer != nullptr);
|
||||
assert(pipe != nullptr);
|
||||
assert(chunk != nullptr);
|
||||
assert(chunk->CheckFormat(input_audio_format));
|
||||
|
||||
if (!Update()) {
|
||||
if (!Update())
|
||||
/* TODO: obtain real error */
|
||||
error.Set(output_domain, "Failed to open audio output");
|
||||
return false;
|
||||
}
|
||||
throw std::runtime_error("Failed to open audio output");
|
||||
|
||||
pipe->Push(chunk);
|
||||
|
||||
for (auto ao : outputs)
|
||||
ao->LockPlay();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
void
|
||||
MultipleOutputs::Open(const AudioFormat audio_format,
|
||||
MusicBuffer &_buffer,
|
||||
Error &error)
|
||||
MusicBuffer &_buffer)
|
||||
{
|
||||
bool ret = false, enabled = false;
|
||||
|
||||
@ -251,17 +240,16 @@ MultipleOutputs::Open(const AudioFormat audio_format,
|
||||
ret = true;
|
||||
}
|
||||
|
||||
if (!enabled)
|
||||
error.Set(output_domain, "All audio outputs are disabled");
|
||||
else if (!ret)
|
||||
/* TODO: obtain real error */
|
||||
error.Set(output_domain, "Failed to open audio output");
|
||||
|
||||
if (!ret)
|
||||
if (!enabled) {
|
||||
/* close all devices if there was an error */
|
||||
Close();
|
||||
|
||||
return ret;
|
||||
throw std::runtime_error("All audio outputs are disabled");
|
||||
} else if (!ret) {
|
||||
/* close all devices if there was an error */
|
||||
Close();
|
||||
/* TODO: obtain real error */
|
||||
throw std::runtime_error("Failed to open audio output");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -118,13 +118,13 @@ public:
|
||||
/**
|
||||
* Opens all audio outputs which are not disabled.
|
||||
*
|
||||
* Throws #std::runtime_error on error.
|
||||
*
|
||||
* @param audio_format the preferred audio format
|
||||
* @param _buffer the #music_buffer where consumed #MusicChunk objects
|
||||
* should be returned
|
||||
* @return true on success, false on failure
|
||||
*/
|
||||
bool Open(const AudioFormat audio_format, MusicBuffer &_buffer,
|
||||
Error &error);
|
||||
void Open(const AudioFormat audio_format, MusicBuffer &_buffer);
|
||||
|
||||
/**
|
||||
* Closes all audio outputs.
|
||||
@ -143,11 +143,11 @@ public:
|
||||
* Enqueue a #MusicChunk object for playing, i.e. pushes it to a
|
||||
* #MusicPipe.
|
||||
*
|
||||
* Throws #std::runtime_error on error (all closed then).
|
||||
*
|
||||
* @param chunk the #MusicChunk object to be played
|
||||
* @return true on success, false if no audio output was able to play
|
||||
* (all closed then)
|
||||
*/
|
||||
bool Play(MusicChunk *chunk, Error &error);
|
||||
void Play(MusicChunk *chunk);
|
||||
|
||||
/**
|
||||
* Checks if the output devices have drained their music pipe, and
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "thread/Name.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <stdexcept>
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static constexpr Domain player_domain("player");
|
||||
@ -443,20 +445,10 @@ Player::OpenOutput()
|
||||
assert(pc.state == PlayerState::PLAY ||
|
||||
pc.state == PlayerState::PAUSE);
|
||||
|
||||
Error error;
|
||||
if (pc.outputs.Open(play_audio_format, buffer, error)) {
|
||||
output_open = true;
|
||||
paused = false;
|
||||
|
||||
pc.Lock();
|
||||
pc.state = PlayerState::PLAY;
|
||||
pc.Unlock();
|
||||
|
||||
idle_add(IDLE_PLAYER);
|
||||
|
||||
return true;
|
||||
} else {
|
||||
LogError(error);
|
||||
try {
|
||||
pc.outputs.Open(play_audio_format, buffer);
|
||||
} catch (const std::runtime_error &e) {
|
||||
LogError(e);
|
||||
|
||||
output_open = false;
|
||||
|
||||
@ -465,7 +457,7 @@ Player::OpenOutput()
|
||||
paused = true;
|
||||
|
||||
pc.Lock();
|
||||
pc.SetError(PlayerError::OUTPUT, std::move(error));
|
||||
pc.SetError(PlayerError::OUTPUT, std::current_exception());
|
||||
pc.state = PlayerState::PAUSE;
|
||||
pc.Unlock();
|
||||
|
||||
@ -473,6 +465,17 @@ Player::OpenOutput()
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
output_open = true;
|
||||
paused = false;
|
||||
|
||||
pc.Lock();
|
||||
pc.state = PlayerState::PLAY;
|
||||
pc.Unlock();
|
||||
|
||||
idle_add(IDLE_PLAYER);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
@ -556,9 +559,10 @@ Player::SendSilence()
|
||||
chunk->length = num_frames * frame_size;
|
||||
PcmSilence({chunk->data, chunk->length}, play_audio_format.format);
|
||||
|
||||
Error error;
|
||||
if (!pc.outputs.Play(chunk, error)) {
|
||||
LogError(error);
|
||||
try {
|
||||
pc.outputs.Play(chunk);
|
||||
} catch (const std::runtime_error &e) {
|
||||
LogError(e);
|
||||
buffer.Return(chunk);
|
||||
return false;
|
||||
}
|
||||
@ -770,12 +774,11 @@ update_song_tag(PlayerControl &pc, DetachedSong &song, const Tag &new_tag)
|
||||
*
|
||||
* Player lock is not held.
|
||||
*/
|
||||
static bool
|
||||
static void
|
||||
play_chunk(PlayerControl &pc,
|
||||
DetachedSong &song, MusicChunk *chunk,
|
||||
MusicBuffer &buffer,
|
||||
const AudioFormat format,
|
||||
Error &error)
|
||||
const AudioFormat format)
|
||||
{
|
||||
assert(chunk->CheckFormat(format));
|
||||
|
||||
@ -784,7 +787,7 @@ play_chunk(PlayerControl &pc,
|
||||
|
||||
if (chunk->IsEmpty()) {
|
||||
buffer.Return(chunk);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
pc.Lock();
|
||||
@ -793,12 +796,9 @@ play_chunk(PlayerControl &pc,
|
||||
|
||||
/* send the chunk to the audio outputs */
|
||||
|
||||
if (!pc.outputs.Play(chunk, error))
|
||||
return false;
|
||||
|
||||
pc.outputs.Play(chunk);
|
||||
pc.total_play_time += (double)chunk->length /
|
||||
format.GetTimeToSize();
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool
|
||||
@ -899,15 +899,16 @@ Player::PlayNextChunk()
|
||||
|
||||
/* play the current chunk */
|
||||
|
||||
Error error;
|
||||
if (!play_chunk(pc, *song, chunk, buffer, play_audio_format, error)) {
|
||||
LogError(error);
|
||||
try {
|
||||
play_chunk(pc, *song, chunk, buffer, play_audio_format);
|
||||
} catch (const std::runtime_error &e) {
|
||||
LogError(e);
|
||||
|
||||
buffer.Return(chunk);
|
||||
|
||||
pc.Lock();
|
||||
|
||||
pc.SetError(PlayerError::OUTPUT, std::move(error));
|
||||
pc.SetError(PlayerError::OUTPUT, std::current_exception());
|
||||
|
||||
/* pause: the user may resume playback as soon as an
|
||||
audio output becomes available */
|
||||
|
Loading…
Reference in New Issue
Block a user