output/recorder: migrate from class Error to C++ exceptions
This commit is contained in:
parent
d8b6aff23a
commit
dd9ab16d67
@ -31,7 +31,7 @@
|
|||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "fs/io/FileOutputStream.hxx"
|
#include "fs/io/FileOutputStream.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/ScopeExit.hxx"
|
#include "util/ScopeExit.hxx"
|
||||||
|
|
||||||
@ -75,21 +75,14 @@ class RecorderOutput {
|
|||||||
*/
|
*/
|
||||||
FileOutputStream *file;
|
FileOutputStream *file;
|
||||||
|
|
||||||
RecorderOutput()
|
RecorderOutput(const ConfigBlock &block);
|
||||||
:base(recorder_output_plugin) {}
|
|
||||||
|
|
||||||
~RecorderOutput() {
|
~RecorderOutput() {
|
||||||
delete prepared_encoder;
|
delete prepared_encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Initialize(const ConfigBlock &block, Error &error_r) {
|
|
||||||
return base.Configure(block, error_r);
|
|
||||||
}
|
|
||||||
|
|
||||||
static RecorderOutput *Create(const ConfigBlock &block, Error &error);
|
static RecorderOutput *Create(const ConfigBlock &block, Error &error);
|
||||||
|
|
||||||
bool Configure(const ConfigBlock &block, Error &error);
|
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
bool Open(AudioFormat &audio_format, Error &error);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
@ -116,22 +109,19 @@ private:
|
|||||||
void Commit();
|
void Commit();
|
||||||
|
|
||||||
void FinishFormat();
|
void FinishFormat();
|
||||||
bool ReopenFormat(AllocatedPath &&new_path, Error &error);
|
void ReopenFormat(AllocatedPath &&new_path);
|
||||||
};
|
};
|
||||||
|
|
||||||
inline bool
|
RecorderOutput::RecorderOutput(const ConfigBlock &block)
|
||||||
RecorderOutput::Configure(const ConfigBlock &block, Error &error)
|
:base(recorder_output_plugin, block)
|
||||||
{
|
{
|
||||||
/* read configuration */
|
/* read configuration */
|
||||||
|
|
||||||
const char *encoder_name =
|
const char *encoder_name =
|
||||||
block.GetBlockValue("encoder", "vorbis");
|
block.GetBlockValue("encoder", "vorbis");
|
||||||
const auto encoder_plugin = encoder_plugin_get(encoder_name);
|
const auto encoder_plugin = encoder_plugin_get(encoder_name);
|
||||||
if (encoder_plugin == nullptr) {
|
if (encoder_plugin == nullptr)
|
||||||
error.Format(config_domain,
|
throw FormatRuntimeError("No such encoder: %s", encoder_name);
|
||||||
"No such encoder: %s", encoder_name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
path = block.GetPath("path");
|
path = block.GetPath("path");
|
||||||
|
|
||||||
@ -139,44 +129,21 @@ RecorderOutput::Configure(const ConfigBlock &block, Error &error)
|
|||||||
if (fmt != nullptr)
|
if (fmt != nullptr)
|
||||||
format_path = fmt;
|
format_path = fmt;
|
||||||
|
|
||||||
if (path.IsNull() && fmt == nullptr) {
|
if (path.IsNull() && fmt == nullptr)
|
||||||
error.Set(config_domain, "'path' not configured");
|
throw std::runtime_error("'path' not configured");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!path.IsNull() && fmt != nullptr) {
|
if (!path.IsNull() && fmt != nullptr)
|
||||||
error.Set(config_domain, "Cannot have both 'path' and 'format_path'");
|
throw std::runtime_error("Cannot have both 'path' and 'format_path'");
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* initialize encoder */
|
/* initialize encoder */
|
||||||
|
|
||||||
prepared_encoder = encoder_init(*encoder_plugin, block);
|
prepared_encoder = encoder_init(*encoder_plugin, block);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
RecorderOutput *
|
RecorderOutput *
|
||||||
RecorderOutput::Create(const ConfigBlock &block, Error &error)
|
RecorderOutput::Create(const ConfigBlock &block, Error &)
|
||||||
{
|
{
|
||||||
RecorderOutput *recorder = new RecorderOutput();
|
return new RecorderOutput(block);
|
||||||
|
|
||||||
try {
|
|
||||||
if (!recorder->Initialize(block, error)) {
|
|
||||||
delete recorder;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!recorder->Configure(block, error)) {
|
|
||||||
delete recorder;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
} catch (...) {
|
|
||||||
delete recorder;
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
|
|
||||||
return recorder;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -188,19 +155,14 @@ RecorderOutput::EncoderToFile()
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
RecorderOutput::Open(AudioFormat &audio_format, Error &error)
|
RecorderOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
{
|
{
|
||||||
/* create the output file */
|
/* create the output file */
|
||||||
|
|
||||||
if (!HasDynamicPath()) {
|
if (!HasDynamicPath()) {
|
||||||
assert(!path.IsNull());
|
assert(!path.IsNull());
|
||||||
|
|
||||||
try {
|
file = new FileOutputStream(path);
|
||||||
file = new FileOutputStream(path);
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
error.Set(recorder_domain, e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
/* don't open the file just yet; wait until we have
|
/* don't open the file just yet; wait until we have
|
||||||
a tag that we can use to build the path */
|
a tag that we can use to build the path */
|
||||||
@ -221,10 +183,9 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
|
|||||||
if (!HasDynamicPath()) {
|
if (!HasDynamicPath()) {
|
||||||
try {
|
try {
|
||||||
EncoderToFile();
|
EncoderToFile();
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::runtime_error &) {
|
||||||
delete encoder;
|
delete encoder;
|
||||||
error.Set(recorder_domain, e.what());
|
throw;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
/* remember the AudioFormat for ReopenFormat() */
|
/* remember the AudioFormat for ReopenFormat() */
|
||||||
@ -308,20 +269,14 @@ RecorderOutput::FinishFormat()
|
|||||||
path.SetNull();
|
path.SetNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
|
RecorderOutput::ReopenFormat(AllocatedPath &&new_path)
|
||||||
{
|
{
|
||||||
assert(HasDynamicPath());
|
assert(HasDynamicPath());
|
||||||
assert(path.IsNull());
|
assert(path.IsNull());
|
||||||
assert(file == nullptr);
|
assert(file == nullptr);
|
||||||
|
|
||||||
FileOutputStream *new_file;
|
FileOutputStream *new_file = new FileOutputStream(path);
|
||||||
try {
|
|
||||||
new_file = new FileOutputStream(path);
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
error.Set(recorder_domain, e.what());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
AudioFormat new_audio_format = effective_audio_format;
|
AudioFormat new_audio_format = effective_audio_format;
|
||||||
|
|
||||||
@ -341,8 +296,7 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
|
|||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
delete encoder;
|
delete encoder;
|
||||||
delete new_file;
|
delete new_file;
|
||||||
error.Set(recorder_domain, e.what());
|
throw;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
path = std::move(new_path);
|
path = std::move(new_path);
|
||||||
@ -350,8 +304,6 @@ RecorderOutput::ReopenFormat(AllocatedPath &&new_path, Error &error)
|
|||||||
|
|
||||||
FormatDebug(recorder_domain, "Recording to \"%s\"",
|
FormatDebug(recorder_domain, "Recording to \"%s\"",
|
||||||
path.ToUTF8().c_str());
|
path.ToUTF8().c_str());
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
@ -382,9 +334,10 @@ RecorderOutput::SendTag(const Tag &tag)
|
|||||||
if (new_path != path) {
|
if (new_path != path) {
|
||||||
FinishFormat();
|
FinishFormat();
|
||||||
|
|
||||||
Error error;
|
try {
|
||||||
if (!ReopenFormat(std::move(new_path), error)) {
|
ReopenFormat(std::move(new_path));
|
||||||
LogError(error);
|
} catch (const std::runtime_error &e) {
|
||||||
|
LogError(e);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -396,7 +349,7 @@ RecorderOutput::SendTag(const Tag &tag)
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
RecorderOutput::Play(const void *chunk, size_t size, Error &error)
|
RecorderOutput::Play(const void *chunk, size_t size, Error &)
|
||||||
{
|
{
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
/* not currently encoding to a file; discard incoming
|
/* not currently encoding to a file; discard incoming
|
||||||
@ -408,12 +361,7 @@ RecorderOutput::Play(const void *chunk, size_t size, Error &error)
|
|||||||
|
|
||||||
encoder->Write(chunk, size);
|
encoder->Write(chunk, size);
|
||||||
|
|
||||||
try {
|
EncoderToFile();
|
||||||
EncoderToFile();
|
|
||||||
} catch (const std::exception &e) {
|
|
||||||
error.Set(recorder_domain, e.what());
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user