summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/Main.cxx5
-rw-r--r--src/decoder/DecoderAPI.cxx25
-rw-r--r--src/filter/plugins/ConvertFilterPlugin.cxx12
-rw-r--r--src/filter/plugins/ReplayGainFilterPlugin.cxx4
-rw-r--r--src/filter/plugins/VolumeFilterPlugin.cxx5
-rw-r--r--src/pcm/ChannelsConverter.cxx16
-rw-r--r--src/pcm/ChannelsConverter.hxx18
-rw-r--r--src/pcm/ConfiguredResampler.cxx40
-rw-r--r--src/pcm/ConfiguredResampler.hxx5
-rw-r--r--src/pcm/FallbackResampler.cxx5
-rw-r--r--src/pcm/FallbackResampler.hxx8
-rw-r--r--src/pcm/FormatConverter.cxx19
-rw-r--r--src/pcm/FormatConverter.hxx16
-rw-r--r--src/pcm/GlueResampler.cxx30
-rw-r--r--src/pcm/GlueResampler.hxx6
-rw-r--r--src/pcm/LibsamplerateResampler.cxx54
-rw-r--r--src/pcm/LibsamplerateResampler.hxx14
-rw-r--r--src/pcm/PcmConvert.cxx81
-rw-r--r--src/pcm/PcmConvert.hxx17
-rw-r--r--src/pcm/Resampler.hxx19
-rw-r--r--src/pcm/SoxrResampler.cxx33
-rw-r--r--src/pcm/SoxrResampler.hxx12
-rw-r--r--src/pcm/Volume.cxx13
-rw-r--r--src/pcm/Volume.hxx7
-rw-r--r--test/run_convert.cxx20
-rw-r--r--test/software_volume.cxx13
-rw-r--r--test/test_pcm_volume.cxx5
27 files changed, 197 insertions, 305 deletions
diff --git a/src/Main.cxx b/src/Main.cxx
index cb93a4c13..5838eeeae 100644
--- a/src/Main.cxx
+++ b/src/Main.cxx
@@ -520,10 +520,7 @@ try {
archive_plugin_init_all();
#endif
- if (!pcm_convert_global_init(error)) {
- LogError(error);
- return EXIT_FAILURE;
- }
+ pcm_convert_global_init();
decoder_plugin_init_all();
diff --git a/src/decoder/DecoderAPI.cxx b/src/decoder/DecoderAPI.cxx
index 87bbd0b13..cfcb44766 100644
--- a/src/decoder/DecoderAPI.cxx
+++ b/src/decoder/DecoderAPI.cxx
@@ -73,11 +73,12 @@ decoder_initialized(Decoder &decoder,
decoder.convert = new PcmConvert();
- Error error;
- if (!decoder.convert->Open(dc.in_audio_format,
- dc.out_audio_format,
- error))
- decoder.error = std::make_exception_ptr(std::move(error));
+ try {
+ decoder.convert->Open(dc.in_audio_format,
+ dc.out_audio_format);
+ } catch (...) {
+ decoder.error = std::current_exception();
+ }
}
const ScopeLock protect(dc.mutex);
@@ -484,19 +485,17 @@ decoder_data(Decoder &decoder,
if (decoder.convert != nullptr) {
assert(dc.in_audio_format != dc.out_audio_format);
- Error error;
- auto result = decoder.convert->Convert({data, length},
- error);
- if (data == nullptr) {
+ try {
+ auto result = decoder.convert->Convert({data, length});
+ data = result.data;
+ length = result.size;
+ } catch (const std::runtime_error &e) {
/* the PCM conversion has failed - stop
playback, since we have no better way to
bail out */
- LogError(error);
+ LogError(e);
return DecoderCommand::STOP;
}
-
- data = result.data;
- length = result.size;
} else {
assert(dc.in_audio_format == dc.out_audio_format);
}
diff --git a/src/filter/plugins/ConvertFilterPlugin.cxx b/src/filter/plugins/ConvertFilterPlugin.cxx
index f4dc37d73..55224de78 100644
--- a/src/filter/plugins/ConvertFilterPlugin.cxx
+++ b/src/filter/plugins/ConvertFilterPlugin.cxx
@@ -25,7 +25,6 @@
#include "pcm/PcmConvert.hxx"
#include "util/Manual.hxx"
#include "util/ConstBuffer.hxx"
-#include "util/Error.hxx"
#include "AudioFormat.hxx"
#include "poison.h"
@@ -88,9 +87,7 @@ ConvertFilter::Set(const AudioFormat &_out_audio_format)
/* optimized special case: no-op */
return;
- Error error;
- if (!state.Open(in_audio_format, _out_audio_format, error))
- throw std::runtime_error(error.GetMessage());
+ state.Open(in_audio_format, _out_audio_format);
out_audio_format = _out_audio_format;
}
@@ -125,12 +122,7 @@ ConvertFilter::FilterPCM(ConstBuffer<void> src)
/* optimized special case: no-op */
return src;
- Error error;
- auto result = state.Convert(src, error);
- if (result.IsNull())
- throw std::runtime_error(error.GetMessage());
-
- return result;
+ return state.Convert(src);
}
const struct filter_plugin convert_filter_plugin = {
diff --git a/src/filter/plugins/ReplayGainFilterPlugin.cxx b/src/filter/plugins/ReplayGainFilterPlugin.cxx
index b6c212c46..4e62d93c2 100644
--- a/src/filter/plugins/ReplayGainFilterPlugin.cxx
+++ b/src/filter/plugins/ReplayGainFilterPlugin.cxx
@@ -76,9 +76,7 @@ public:
mixer(_mixer), base(_base), mode(REPLAY_GAIN_OFF) {
info.Clear();
- Error error;
- if (!pv.Open(out_audio_format.format, error))
- throw std::runtime_error(error.GetMessage());
+ pv.Open(out_audio_format.format);
}
void SetInfo(const ReplayGainInfo *_info) {
diff --git a/src/filter/plugins/VolumeFilterPlugin.cxx b/src/filter/plugins/VolumeFilterPlugin.cxx
index 5ed86d222..64959916f 100644
--- a/src/filter/plugins/VolumeFilterPlugin.cxx
+++ b/src/filter/plugins/VolumeFilterPlugin.cxx
@@ -25,7 +25,6 @@
#include "pcm/Volume.hxx"
#include "AudioFormat.hxx"
#include "util/ConstBuffer.hxx"
-#include "util/Error.hxx"
#include <stdexcept>
@@ -35,9 +34,7 @@ class VolumeFilter final : public Filter {
public:
explicit VolumeFilter(const AudioFormat &audio_format)
:Filter(audio_format) {
- Error error;
- if (!pv.Open(out_audio_format.format, error))
- throw std::runtime_error(error.GetMessage());
+ pv.Open(out_audio_format.format);
}
unsigned GetVolume() const {
diff --git a/src/pcm/ChannelsConverter.cxx b/src/pcm/ChannelsConverter.cxx
index ec0024581..cd6184f76 100644
--- a/src/pcm/ChannelsConverter.cxx
+++ b/src/pcm/ChannelsConverter.cxx
@@ -22,14 +22,13 @@
#include "PcmChannels.hxx"
#include "Domain.hxx"
#include "util/ConstBuffer.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#include <assert.h>
-bool
+void
PcmChannelsConverter::Open(SampleFormat _format,
- unsigned _src_channels, unsigned _dest_channels,
- gcc_unused Error &error)
+ unsigned _src_channels, unsigned _dest_channels)
{
assert(_format != SampleFormat::UNDEFINED);
@@ -41,16 +40,13 @@ PcmChannelsConverter::Open(SampleFormat _format,
break;
default:
- error.Format(pcm_domain,
- "PCM channel conversion for %s is not implemented",
- sample_format_to_string(_format));
- return false;
+ throw FormatRuntimeError("PCM channel conversion for %s is not implemented",
+ sample_format_to_string(_format));
}
format = _format;
src_channels = _src_channels;
dest_channels = _dest_channels;
- return true;
}
void
@@ -62,7 +58,7 @@ PcmChannelsConverter::Close()
}
ConstBuffer<void>
-PcmChannelsConverter::Convert(ConstBuffer<void> src, gcc_unused Error &error)
+PcmChannelsConverter::Convert(ConstBuffer<void> src)
{
switch (format) {
case SampleFormat::UNDEFINED:
diff --git a/src/pcm/ChannelsConverter.hxx b/src/pcm/ChannelsConverter.hxx
index ce893a20f..8ad3ac5ee 100644
--- a/src/pcm/ChannelsConverter.hxx
+++ b/src/pcm/ChannelsConverter.hxx
@@ -28,7 +28,6 @@
#include <assert.h>
#endif
-class Error;
template<typename T> struct ConstBuffer;
/**
@@ -53,15 +52,14 @@ public:
/**
* Opens the object, prepare for Convert().
*
+ * Throws std::runtime_error on error.
+ *
* @param format the sample format
* @param src_channels the number of source channels
* @param dest_channels the number of destination channels
- * @param error location to store the error
- * @return true on success
*/
- bool Open(SampleFormat format,
- unsigned src_channels, unsigned dest_channels,
- Error &error);
+ void Open(SampleFormat format,
+ unsigned src_channels, unsigned dest_channels);
/**
* Closes the object. After that, you may call Open() again.
@@ -71,13 +69,13 @@ public:
/**
* Convert a block of PCM data.
*
+ * Throws std::runtime_error on error.
+ *
* @param src the input buffer
- * @param error location to store the error
- * @return the destination buffer on success,
- * ConstBuffer::Null() on error
+ * @return the destination buffer
*/
gcc_pure
- ConstBuffer<void> Convert(ConstBuffer<void> src, Error &error);
+ ConstBuffer<void> Convert(ConstBuffer<void> src);
};
#endif
diff --git a/src/pcm/ConfiguredResampler.cxx b/src/pcm/ConfiguredResampler.cxx
index 382eaf258..f66bf8a3f 100644
--- a/src/pcm/ConfiguredResampler.cxx
+++ b/src/pcm/ConfiguredResampler.cxx
@@ -25,7 +25,7 @@
#include "config/ConfigError.hxx"
#include "config/Block.hxx"
#include "config/Param.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#ifdef ENABLE_LIBSAMPLERATE
#include "LibsamplerateResampler.hxx"
@@ -112,7 +112,7 @@ MigrateResamplerConfig(const config_param *param, ConfigBlock &buffer)
}
static const ConfigBlock *
-GetResamplerConfig(ConfigBlock &buffer, Error &error)
+GetResamplerConfig(ConfigBlock &buffer)
{
const auto *old_param =
config_get_param(ConfigOption::SAMPLERATE_CONVERTER);
@@ -120,49 +120,39 @@ GetResamplerConfig(ConfigBlock &buffer, Error &error)
if (block == nullptr)
return MigrateResamplerConfig(old_param, buffer);
- if (old_param != nullptr) {
- error.Format(config_domain,
- "Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)",
- block->line, old_param->line);
- return nullptr;
- }
+ if (old_param != nullptr)
+ throw FormatRuntimeError("Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)",
+ block->line, old_param->line);
return block;
}
-bool
-pcm_resampler_global_init(Error &error)
+void
+pcm_resampler_global_init()
{
ConfigBlock buffer;
- const auto *block = GetResamplerConfig(buffer, error);
- if (block == nullptr)
- return false;
+ const auto *block = GetResamplerConfig(buffer);
const char *plugin_name = block->GetBlockValue("plugin");
- if (plugin_name == nullptr) {
- error.Format(config_domain,
- "'plugin' missing in line %d", block->line);
- return false;
- }
+ if (plugin_name == nullptr)
+ throw FormatRuntimeError("'plugin' missing in line %d",
+ block->line);
if (strcmp(plugin_name, "internal") == 0) {
selected_resampler = SelectedResampler::FALLBACK;
- return true;
#ifdef ENABLE_SOXR
} else if (strcmp(plugin_name, "soxr") == 0) {
selected_resampler = SelectedResampler::SOXR;
- return pcm_resample_soxr_global_init(*block, error);
+ pcm_resample_soxr_global_init(*block);
#endif
#ifdef ENABLE_LIBSAMPLERATE
} else if (strcmp(plugin_name, "libsamplerate") == 0) {
selected_resampler = SelectedResampler::LIBSAMPLERATE;
- return pcm_resample_lsr_global_init(*block, error);
+ pcm_resample_lsr_global_init(*block);
#endif
} else {
- error.Format(config_domain,
- "No such resampler plugin: %s",
- plugin_name);
- return false;
+ throw FormatRuntimeError("No such resampler plugin: %s",
+ plugin_name);
}
}
diff --git a/src/pcm/ConfiguredResampler.hxx b/src/pcm/ConfiguredResampler.hxx
index b871f1caf..1279faa57 100644
--- a/src/pcm/ConfiguredResampler.hxx
+++ b/src/pcm/ConfiguredResampler.hxx
@@ -22,11 +22,10 @@
#include "check.h"
-class Error;
class PcmResampler;
-bool
-pcm_resampler_global_init(Error &error);
+void
+pcm_resampler_global_init();
/**
* Create a #PcmResampler instance from the implementation class
diff --git a/src/pcm/FallbackResampler.cxx b/src/pcm/FallbackResampler.cxx
index 61bdc1ed9..e57073d88 100644
--- a/src/pcm/FallbackResampler.cxx
+++ b/src/pcm/FallbackResampler.cxx
@@ -23,8 +23,7 @@
#include <assert.h>
AudioFormat
-FallbackPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
- gcc_unused Error &error)
+FallbackPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate)
{
assert(af.IsValid());
assert(audio_valid_sample_rate(new_sample_rate));
@@ -116,7 +115,7 @@ pcm_resample_fallback_void(PcmBuffer &buffer,
}
ConstBuffer<void>
-FallbackPcmResampler::Resample(ConstBuffer<void> src, gcc_unused Error &error)
+FallbackPcmResampler::Resample(ConstBuffer<void> src)
{
switch (format.format) {
case SampleFormat::UNDEFINED:
diff --git a/src/pcm/FallbackResampler.hxx b/src/pcm/FallbackResampler.hxx
index 04944b301..c70494b4e 100644
--- a/src/pcm/FallbackResampler.hxx
+++ b/src/pcm/FallbackResampler.hxx
@@ -36,11 +36,9 @@ class FallbackPcmResampler final : public PcmResampler {
PcmBuffer buffer;
public:
- virtual AudioFormat Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error) override;
- virtual void Close() override;
- virtual ConstBuffer<void> Resample(ConstBuffer<void> src,
- Error &error) override;
+ AudioFormat Open(AudioFormat &af, unsigned new_sample_rate) override;
+ void Close() override;
+ ConstBuffer<void> Resample(ConstBuffer<void> src) override;
};
#endif
diff --git a/src/pcm/FormatConverter.cxx b/src/pcm/FormatConverter.cxx
index ae52ec7c2..d51b9397c 100644
--- a/src/pcm/FormatConverter.cxx
+++ b/src/pcm/FormatConverter.cxx
@@ -20,15 +20,13 @@
#include "config.h"
#include "FormatConverter.hxx"
#include "PcmFormat.hxx"
-#include "Domain.hxx"
#include "util/ConstBuffer.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#include <assert.h>
-bool
-PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format,
- Error &error)
+void
+PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format)
{
assert(_src_format != SampleFormat::UNDEFINED);
assert(_dest_format != SampleFormat::UNDEFINED);
@@ -40,11 +38,9 @@ PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format,
case SampleFormat::S8:
case SampleFormat::DSD:
- error.Format(pcm_domain,
- "PCM conversion from %s to %s is not implemented",
- sample_format_to_string(_src_format),
- sample_format_to_string(_dest_format));
- return false;
+ throw FormatRuntimeError("PCM conversion from %s to %s is not implemented",
+ sample_format_to_string(_src_format),
+ sample_format_to_string(_dest_format));
case SampleFormat::S16:
case SampleFormat::S24_P32:
@@ -55,7 +51,6 @@ PcmFormatConverter::Open(SampleFormat _src_format, SampleFormat _dest_format,
src_format = _src_format;
dest_format = _dest_format;
- return true;
}
void
@@ -68,7 +63,7 @@ PcmFormatConverter::Close()
}
ConstBuffer<void>
-PcmFormatConverter::Convert(ConstBuffer<void> src, gcc_unused Error &error)
+PcmFormatConverter::Convert(ConstBuffer<void> src)
{
switch (dest_format) {
case SampleFormat::UNDEFINED:
diff --git a/src/pcm/FormatConverter.hxx b/src/pcm/FormatConverter.hxx
index d7368e7e1..a9cd42a0e 100644
--- a/src/pcm/FormatConverter.hxx
+++ b/src/pcm/FormatConverter.hxx
@@ -29,7 +29,6 @@
#include <assert.h>
#endif
-class Error;
template<typename T> struct ConstBuffer;
/**
@@ -56,13 +55,12 @@ public:
/**
* Opens the object, prepare for Convert().
*
+ * Throws std::runtime_error on error.
+ *
* @param src_format the sample format of incoming data
* @param dest_format the sample format of outgoing data
- * @param error location to store the error
- * @return true on success
*/
- bool Open(SampleFormat src_format, SampleFormat dest_format,
- Error &error);
+ void Open(SampleFormat src_format, SampleFormat dest_format);
/**
* Closes the object. After that, you may call Open() again.
@@ -72,13 +70,13 @@ public:
/**
* Convert a block of PCM data.
*
+ * Throws std::runtime_error on error.
+ *
* @param src the input buffer
- * @param error location to store the error
- * @return the destination buffer on success,
- * ConstBuffer::Null() on error
+ * @return the destination buffer
*/
gcc_pure
- ConstBuffer<void> Convert(ConstBuffer<void> src, Error &error);
+ ConstBuffer<void> Convert(ConstBuffer<void> src);
};
#endif
diff --git a/src/pcm/GlueResampler.cxx b/src/pcm/GlueResampler.cxx
index 37b12584a..bf8f995eb 100644
--- a/src/pcm/GlueResampler.cxx
+++ b/src/pcm/GlueResampler.cxx
@@ -32,33 +32,28 @@ GluePcmResampler::~GluePcmResampler()
delete resampler;
}
-bool
-GluePcmResampler::Open(AudioFormat src_format, unsigned new_sample_rate,
- Error &error)
+void
+GluePcmResampler::Open(AudioFormat src_format, unsigned new_sample_rate)
{
assert(src_format.IsValid());
assert(audio_valid_sample_rate(new_sample_rate));
AudioFormat requested_format = src_format;
AudioFormat dest_format = resampler->Open(requested_format,
- new_sample_rate,
- error);
- if (!dest_format.IsValid())
- return false;
+ new_sample_rate);
+ assert(dest_format.IsValid());
assert(requested_format.channels == src_format.channels);
assert(dest_format.channels == src_format.channels);
assert(dest_format.sample_rate == new_sample_rate);
- if (requested_format.format != src_format.format &&
- !format_converter.Open(src_format.format, requested_format.format,
- error))
- return false;
+ if (requested_format.format != src_format.format)
+ format_converter.Open(src_format.format,
+ requested_format.format);
src_sample_format = src_format.format;
requested_sample_format = requested_format.format;
output_sample_format = dest_format.format;
- return true;
}
void
@@ -71,15 +66,12 @@ GluePcmResampler::Close()
}
ConstBuffer<void>
-GluePcmResampler::Resample(ConstBuffer<void> src, Error &error)
+GluePcmResampler::Resample(ConstBuffer<void> src)
{
assert(!src.IsNull());
- if (requested_sample_format != src_sample_format) {
- src = format_converter.Convert(src, error);
- if (src.IsNull())
- return nullptr;
- }
+ if (requested_sample_format != src_sample_format)
+ src = format_converter.Convert(src);
- return resampler->Resample(src, error);
+ return resampler->Resample(src);
}
diff --git a/src/pcm/GlueResampler.hxx b/src/pcm/GlueResampler.hxx
index e2107e478..da0d81e49 100644
--- a/src/pcm/GlueResampler.hxx
+++ b/src/pcm/GlueResampler.hxx
@@ -24,7 +24,6 @@
#include "AudioFormat.hxx"
#include "FormatConverter.hxx"
-class Error;
class PcmResampler;
template<typename T> struct ConstBuffer;
@@ -49,15 +48,14 @@ public:
GluePcmResampler();
~GluePcmResampler();
- bool Open(AudioFormat src_format, unsigned new_sample_rate,
- Error &error);
+ void Open(AudioFormat src_format, unsigned new_sample_rate);
void Close();
SampleFormat GetOutputSampleFormat() const {
return output_sample_format;
}
- ConstBuffer<void> Resample(ConstBuffer<void> src, Error &error);
+ ConstBuffer<void> Resample(ConstBuffer<void> src);
};
#endif
diff --git a/src/pcm/LibsamplerateResampler.cxx b/src/pcm/LibsamplerateResampler.cxx
index b660cb995..7c0637635 100644
--- a/src/pcm/LibsamplerateResampler.cxx
+++ b/src/pcm/LibsamplerateResampler.cxx
@@ -21,7 +21,7 @@
#include "LibsamplerateResampler.hxx"
#include "config/Block.hxx"
#include "util/ASCII.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -63,26 +63,21 @@ lsr_parse_converter(const char *s)
return false;
}
-bool
-pcm_resample_lsr_global_init(const ConfigBlock &block, Error &error)
+void
+pcm_resample_lsr_global_init(const ConfigBlock &block)
{
const char *converter = block.GetBlockValue("type", "2");
- if (!lsr_parse_converter(converter)) {
- error.Format(libsamplerate_domain,
- "unknown samplerate converter '%s'", converter);
- return false;
- }
+ if (!lsr_parse_converter(converter))
+ throw FormatRuntimeError("unknown samplerate converter '%s'",
+ converter);
FormatDebug(libsamplerate_domain,
"libsamplerate converter '%s'",
src_get_name(lsr_converter));
-
- return true;
}
AudioFormat
-LibsampleratePcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error)
+LibsampleratePcmResampler::Open(AudioFormat &af, unsigned new_sample_rate)
{
assert(af.IsValid());
assert(audio_valid_sample_rate(new_sample_rate));
@@ -96,12 +91,9 @@ LibsampleratePcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
int src_error;
state = src_new(lsr_converter, channels, &src_error);
- if (!state) {
- error.Format(libsamplerate_domain, src_error,
- "libsamplerate initialization has failed: %s",
- src_strerror(src_error));
- return AudioFormat::Undefined();
- }
+ if (!state)
+ throw FormatRuntimeError("libsamplerate initialization has failed: %s",
+ src_strerror(src_error));
memset(&data, 0, sizeof(data));
@@ -122,22 +114,8 @@ LibsampleratePcmResampler::Close()
state = src_delete(state);
}
-static bool
-src_process(SRC_STATE *state, SRC_DATA *data, Error &error)
-{
- int result = src_process(state, data);
- if (result != 0) {
- error.Format(libsamplerate_domain, result,
- "libsamplerate has failed: %s",
- src_strerror(result));
- return false;
- }
-
- return true;
-}
-
inline ConstBuffer<float>
-LibsampleratePcmResampler::Resample2(ConstBuffer<float> src, Error &error)
+LibsampleratePcmResampler::Resample2(ConstBuffer<float> src)
{
assert(src.size % channels == 0);
@@ -151,15 +129,17 @@ LibsampleratePcmResampler::Resample2(ConstBuffer<float> src, Error &error)
data.input_frames = src_frames;
data.output_frames = dest_frames;
- if (!src_process(state, &data, error))
- return nullptr;
+ int result = src_process(state, &data);
+ if (result != 0)
+ throw FormatRuntimeError("libsamplerate has failed: %s",
+ src_strerror(result));
return ConstBuffer<float>(data.data_out,
data.output_frames_gen * channels);
}
ConstBuffer<void>
-LibsampleratePcmResampler::Resample(ConstBuffer<void> src, Error &error)
+LibsampleratePcmResampler::Resample(ConstBuffer<void> src)
{
- return Resample2(ConstBuffer<float>::FromVoid(src), error).ToVoid();
+ return Resample2(ConstBuffer<float>::FromVoid(src)).ToVoid();
}
diff --git a/src/pcm/LibsamplerateResampler.hxx b/src/pcm/LibsamplerateResampler.hxx
index 8161219c2..3c4c9bcd8 100644
--- a/src/pcm/LibsamplerateResampler.hxx
+++ b/src/pcm/LibsamplerateResampler.hxx
@@ -42,17 +42,15 @@ class LibsampleratePcmResampler final : public PcmResampler {
PcmBuffer buffer;
public:
- virtual AudioFormat Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error) override;
- virtual void Close() override;
- virtual ConstBuffer<void> Resample(ConstBuffer<void> src,
- Error &error) override;
+ AudioFormat Open(AudioFormat &af, unsigned new_sample_rate) override;
+ void Close() override;
+ ConstBuffer<void> Resample(ConstBuffer<void> src) override;
private:
- ConstBuffer<float> Resample2(ConstBuffer<float> src, Error &error);
+ ConstBuffer<float> Resample2(ConstBuffer<float> src);
};
-bool
-pcm_resample_lsr_global_init(const ConfigBlock &block, Error &error);
+void
+pcm_resample_lsr_global_init(const ConfigBlock &block);
#endif
diff --git a/src/pcm/PcmConvert.cxx b/src/pcm/PcmConvert.cxx
index 81bec1c75..2470583c8 100644
--- a/src/pcm/PcmConvert.cxx
+++ b/src/pcm/PcmConvert.cxx
@@ -22,15 +22,14 @@
#include "Domain.hxx"
#include "ConfiguredResampler.hxx"
#include "AudioFormat.hxx"
-#include "util/Error.hxx"
#include "util/ConstBuffer.hxx"
#include <assert.h>
-bool
-pcm_convert_global_init(Error &error)
+void
+pcm_convert_global_init()
{
- return pcm_resampler_global_init(error);
+ pcm_resampler_global_init();
}
PcmConvert::PcmConvert()
@@ -47,9 +46,8 @@ PcmConvert::~PcmConvert()
assert(!dest_format.IsValid());
}
-bool
-PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format,
- Error &error)
+void
+PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format)
{
assert(!src_format.IsValid());
assert(!dest_format.IsValid());
@@ -62,39 +60,42 @@ PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format,
enable_resampler = format.sample_rate != _dest_format.sample_rate;
if (enable_resampler) {
- if (!resampler.Open(format, _dest_format.sample_rate, error))
- return false;
+ resampler.Open(format, _dest_format.sample_rate);
format.format = resampler.GetOutputSampleFormat();
format.sample_rate = _dest_format.sample_rate;
}
enable_format = format.format != _dest_format.format;
- if (enable_format &&
- !format_converter.Open(format.format, _dest_format.format,
- error)) {
- if (enable_resampler)
- resampler.Close();
- return false;
+ if (enable_format) {
+ try {
+ format_converter.Open(format.format,
+ _dest_format.format);
+ } catch (...) {
+ if (enable_resampler)
+ resampler.Close();
+ throw;
+ }
}
format.format = _dest_format.format;
enable_channels = format.channels != _dest_format.channels;
- if (enable_channels &&
- !channels_converter.Open(format.format, format.channels,
- _dest_format.channels, error)) {
- if (enable_format)
- format_converter.Close();
- if (enable_resampler)
- resampler.Close();
- return false;
+ if (enable_channels) {
+ try {
+ channels_converter.Open(format.format, format.channels,
+ _dest_format.channels);
+ } catch (...) {
+ if (enable_format)
+ format_converter.Close();
+ if (enable_resampler)
+ resampler.Close();
+ throw;
+ }
}
src_format = _src_format;
dest_format = _dest_format;
-
- return true;
}
void
@@ -118,39 +119,27 @@ PcmConvert::Close()
}
ConstBuffer<void>
-PcmConvert::Convert(ConstBuffer<void> buffer, Error &error)
+PcmConvert::Convert(ConstBuffer<void> buffer)
{
#ifdef ENABLE_DSD
if (src_format.format == SampleFormat::DSD) {
auto s = ConstBuffer<uint8_t>::FromVoid(buffer);
auto d = dsd.ToFloat(src_format.channels, s);
- if (d.IsNull()) {
- error.Set(pcm_domain,
- "DSD to PCM conversion failed");
- return nullptr;
- }
+ if (d.IsNull())
+ throw std::runtime_error("DSD to PCM conversion failed");
buffer = d.ToVoid();
}
#endif
- if (enable_resampler) {
- buffer = resampler.Resample(buffer, error);
- if (buffer.IsNull())
- return nullptr;
- }
+ if (enable_resampler)
+ buffer = resampler.Resample(buffer);
- if (enable_format) {
- buffer = format_converter.Convert(buffer, error);
- if (buffer.IsNull())
- return nullptr;
- }
+ if (enable_format)
+ buffer = format_converter.Convert(buffer);
- if (enable_channels) {
- buffer = channels_converter.Convert(buffer, error);
- if (buffer.IsNull())
- return nullptr;
- }
+ if (enable_channels)
+ buffer = channels_converter.Convert(buffer);
return buffer;
}
diff --git a/src/pcm/PcmConvert.hxx b/src/pcm/PcmConvert.hxx
index 8b49c001f..c717a6ae2 100644
--- a/src/pcm/PcmConvert.hxx
+++ b/src/pcm/PcmConvert.hxx
@@ -31,7 +31,6 @@
#endif
template<typename T> struct ConstBuffer;
-class Error;
/**
* This object is statically allocated (within another struct), and
@@ -57,9 +56,10 @@ public:
/**
* Prepare the object. Call Close() when done.
+ *
+ * Throws std::runtime_error on error.
*/
- bool Open(AudioFormat _src_format, AudioFormat _dest_format,
- Error &error);
+ void Open(AudioFormat _src_format, AudioFormat _dest_format);
/**
* Close the object after it was prepared with Open(). After
@@ -70,14 +70,15 @@ public:
/**
* Converts PCM data between two audio formats.
*
+ * Throws std::runtime_error on error.
+ *
* @param src the source PCM buffer
- * @param error location to store the error occurring
- * @return the destination buffer, or nullptr on error
+ * @return the destination buffer
*/
- ConstBuffer<void> Convert(ConstBuffer<void> src, Error &error);
+ ConstBuffer<void> Convert(ConstBuffer<void> src);
};
-bool
-pcm_convert_global_init(Error &error);
+void
+pcm_convert_global_init();
#endif
diff --git a/src/pcm/Resampler.hxx b/src/pcm/Resampler.hxx
index b88ebf161..404a7db28 100644
--- a/src/pcm/Resampler.hxx
+++ b/src/pcm/Resampler.hxx
@@ -24,7 +24,6 @@
#include "Compiler.h"
struct AudioFormat;
-class Error;
/**
* This is an interface for plugins that convert PCM data to a
@@ -37,16 +36,17 @@ public:
/**
* Opens the resampler, preparing it for Resample().
*
+ * Throws std::runtime_error on error.
+ *
* @param af the audio format of incoming data; the plugin may
* modify the object to enforce another input format (however,
* it may not request a different input sample rate)
* @param new_sample_rate the requested output sample rate
* @param error location to store the error
- * @return the format of outgoing data or
- * AudioFormat::Undefined() on error
+ * @return the format of outgoing data
*/
- virtual AudioFormat Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error) = 0;
+ virtual AudioFormat Open(AudioFormat &af,
+ unsigned new_sample_rate) = 0;
/**
* Closes the resampler. After that, you may call Open()
@@ -58,14 +58,11 @@ public:
* Resamples a block of PCM data.
*
* @param src the input buffer
- * @param error location to store the error occurring
- * @return the destination buffer on success (will be
- * invalidated by filter_close() or filter_filter()), nullptr on
- * error
+ * @return the destination buffer (will be invalidated by
+ * filter_close() or filter_filter())
*/
gcc_pure
- virtual ConstBuffer<void> Resample(ConstBuffer<void> src,
- Error &error) = 0;
+ virtual ConstBuffer<void> Resample(ConstBuffer<void> src) = 0;
};
#endif
diff --git a/src/pcm/SoxrResampler.cxx b/src/pcm/SoxrResampler.cxx
index 1b8002115..c85f58c0b 100644
--- a/src/pcm/SoxrResampler.cxx
+++ b/src/pcm/SoxrResampler.cxx
@@ -21,7 +21,7 @@
#include "SoxrResampler.hxx"
#include "AudioFormat.hxx"
#include "config/Block.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#include "util/Domain.hxx"
#include "Log.hxx"
@@ -80,18 +80,16 @@ soxr_parse_quality(const char *quality)
return SOXR_INVALID_RECIPE;
}
-bool
-pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error)
+void
+pcm_resample_soxr_global_init(const ConfigBlock &block)
{
const char *quality_string = block.GetBlockValue("quality");
unsigned long recipe = soxr_parse_quality(quality_string);
if (recipe == SOXR_INVALID_RECIPE) {
assert(quality_string != nullptr);
- error.Format(soxr_domain,
- "unknown quality setting '%s' in line %d",
- quality_string, block.line);
- return false;
+ throw FormatRuntimeError("unknown quality setting '%s' in line %d",
+ quality_string, block.line);
}
soxr_quality = soxr_quality_spec(recipe, 0);
@@ -102,13 +100,10 @@ pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error)
const unsigned n_threads = block.GetBlockValue("threads", 1);
soxr_runtime = soxr_runtime_spec(n_threads);
-
- return true;
}
AudioFormat
-SoxrPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error)
+SoxrPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate)
{
assert(af.IsValid());
assert(audio_valid_sample_rate(new_sample_rate));
@@ -117,11 +112,9 @@ SoxrPcmResampler::Open(AudioFormat &af, unsigned new_sample_rate,
soxr = soxr_create(af.sample_rate, new_sample_rate,
af.channels, &e,
nullptr, &soxr_quality, &soxr_runtime);
- if (soxr == nullptr) {
- error.Format(soxr_domain,
- "soxr initialization has failed: %s", e);
- return AudioFormat::Undefined();
- }
+ if (soxr == nullptr)
+ throw FormatRuntimeError("soxr initialization has failed: %s",
+ e);
FormatDebug(soxr_domain, "soxr engine '%s'", soxr_engine(soxr));
@@ -147,7 +140,7 @@ SoxrPcmResampler::Close()
}
ConstBuffer<void>
-SoxrPcmResampler::Resample(ConstBuffer<void> src, Error &error)
+SoxrPcmResampler::Resample(ConstBuffer<void> src)
{
const size_t frame_size = channels * sizeof(float);
assert(src.size % frame_size == 0);
@@ -162,10 +155,8 @@ SoxrPcmResampler::Resample(ConstBuffer<void> src, Error &error)
size_t i_done, o_done;
soxr_error_t e = soxr_process(soxr, src.data, n_frames, &i_done,
output_buffer, o_frames, &o_done);
- if (e != nullptr) {
- error.Format(soxr_domain, "soxr error: %s", e);
- return nullptr;
- }
+ if (e != nullptr)
+ throw FormatRuntimeError("soxr error: %s", e);
return { output_buffer, o_done * frame_size };
}
diff --git a/src/pcm/SoxrResampler.hxx b/src/pcm/SoxrResampler.hxx
index 7c7ffd6ed..dc76d3206 100644
--- a/src/pcm/SoxrResampler.hxx
+++ b/src/pcm/SoxrResampler.hxx
@@ -39,14 +39,12 @@ class SoxrPcmResampler final : public PcmResampler {
PcmBuffer buffer;
public:
- virtual AudioFormat Open(AudioFormat &af, unsigned new_sample_rate,
- Error &error) override;
- virtual void Close() override;
- virtual ConstBuffer<void> Resample(ConstBuffer<void> src,
- Error &error) override;
+ AudioFormat Open(AudioFormat &af, unsigned new_sample_rate) override;
+ void Close() override;
+ ConstBuffer<void> Resample(ConstBuffer<void> src) override;
};
-bool
-pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error);
+void
+pcm_resample_soxr_global_init(const ConfigBlock &block);
#endif
diff --git a/src/pcm/Volume.cxx b/src/pcm/Volume.cxx
index 5e09fc3be..a50854190 100644
--- a/src/pcm/Volume.cxx
+++ b/src/pcm/Volume.cxx
@@ -24,7 +24,7 @@
#include "Traits.hxx"
#include "util/ConstBuffer.hxx"
#include "util/WritableBuffer.hxx"
-#include "util/Error.hxx"
+#include "util/RuntimeError.hxx"
#include "PcmDither.cxx" // including the .cxx file to get inlined templates
@@ -97,17 +97,15 @@ pcm_volume_change_float(float *dest, const float *src, size_t n,
dest[i] = src[i] * volume;
}
-bool
-PcmVolume::Open(SampleFormat _format, Error &error)
+void
+PcmVolume::Open(SampleFormat _format)
{
assert(format == SampleFormat::UNDEFINED);
switch (_format) {
case SampleFormat::UNDEFINED:
- error.Format(pcm_domain,
- "Software volume for %s is not implemented",
- sample_format_to_string(_format));
- return false;
+ throw FormatRuntimeError("Software volume for %s is not implemented",
+ sample_format_to_string(_format));
case SampleFormat::S8:
case SampleFormat::S16:
@@ -122,7 +120,6 @@ PcmVolume::Open(SampleFormat _format, Error &error)
}
format = _format;
- return true;
}
ConstBuffer<void>
diff --git a/src/pcm/Volume.hxx b/src/pcm/Volume.hxx
index 1576b33b1..a68dc958f 100644
--- a/src/pcm/Volume.hxx
+++ b/src/pcm/Volume.hxx
@@ -28,7 +28,6 @@
#include <assert.h>
#endif
-class Error;
template<typename T> struct ConstBuffer;
/**
@@ -93,11 +92,11 @@ public:
/**
* Opens the object, prepare for Apply().
*
+ * Throws std::runtime_error on error.
+ *
* @param format the sample format
- * @param error location to store the error
- * @return true on success
*/
- bool Open(SampleFormat format, Error &error);
+ void Open(SampleFormat format);
/**
* Closes the object. After that, you may call Open() again.
diff --git a/test/run_convert.cxx b/test/run_convert.cxx
index 8b89831a5..a07e71f47 100644
--- a/test/run_convert.cxx
+++ b/test/run_convert.cxx
@@ -38,8 +38,9 @@
#include <stdio.h>
#include <unistd.h>
-int main(int argc, char **argv)
-{
+int
+main(int argc, char **argv)
+try {
AudioFormat in_audio_format, out_audio_format;
if (argc != 3) {
@@ -68,10 +69,7 @@ int main(int argc, char **argv)
const size_t in_frame_size = in_audio_format.GetFrameSize();
PcmConvert state;
- if (!state.Open(in_audio_format, out_audio_format_mask, error)) {
- LogError(error, "Failed to open PcmConvert");
- return EXIT_FAILURE;
- }
+ state.Open(in_audio_format, out_audio_format_mask);
StaticFifoBuffer<uint8_t, 4096> buffer;
@@ -96,12 +94,7 @@ int main(int argc, char **argv)
buffer.Consume(src.size);
- auto output = state.Convert({src.data, src.size}, error);
- if (output.IsNull()) {
- state.Close();
- LogError(error, "Failed to convert");
- return EXIT_FAILURE;
- }
+ auto output = state.Convert({src.data, src.size});
gcc_unused ssize_t ignored = write(1, output.data,
output.size);
@@ -110,4 +103,7 @@ int main(int argc, char **argv)
state.Close();
return EXIT_SUCCESS;
+} catch (const std::exception &e) {
+ LogError(e);
+ return EXIT_FAILURE;
}
diff --git a/test/software_volume.cxx b/test/software_volume.cxx
index d0b977ef2..45604b8a1 100644
--- a/test/software_volume.cxx
+++ b/test/software_volume.cxx
@@ -36,8 +36,9 @@
#include <stdlib.h>
#include <unistd.h>
-int main(int argc, char **argv)
-{
+int
+main(int argc, char **argv)
+try {
static char buffer[4096];
ssize_t nbytes;
@@ -56,10 +57,7 @@ int main(int argc, char **argv)
}
PcmVolume pv;
- if (!pv.Open(audio_format.format, error)) {
- fprintf(stderr, "%s\n", error.GetMessage());
- return EXIT_FAILURE;
- }
+ pv.Open(audio_format.format);
while ((nbytes = read(0, buffer, sizeof(buffer))) > 0) {
auto dest = pv.Apply({buffer, size_t(nbytes)});
@@ -67,4 +65,7 @@ int main(int argc, char **argv)
}
pv.Close();
+} catch (const std::exception &e) {
+ LogError(e);
+ return EXIT_FAILURE;
}
diff --git a/test/test_pcm_volume.cxx b/test/test_pcm_volume.cxx
index 9cb693d7d..c774af49d 100644
--- a/test/test_pcm_volume.cxx
+++ b/test/test_pcm_volume.cxx
@@ -22,7 +22,6 @@
#include "pcm/Volume.hxx"
#include "pcm/Traits.hxx"
#include "util/ConstBuffer.hxx"
-#include "util/Error.hxx"
#include "test_pcm_util.hxx"
#include <algorithm>
@@ -37,7 +36,7 @@ TestVolume(G g=G())
typedef typename Traits::value_type value_type;
PcmVolume pv;
- CPPUNIT_ASSERT(pv.Open(F, IgnoreError()));
+ pv.Open(F);
constexpr size_t N = 509;
static value_type zero[N];
@@ -96,7 +95,7 @@ void
PcmVolumeTest::TestVolumeFloat()
{
PcmVolume pv;
- CPPUNIT_ASSERT(pv.Open(SampleFormat::FLOAT, IgnoreError()));
+ pv.Open(SampleFormat::FLOAT);
constexpr size_t N = 509;
static float zero[N];