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