filter/Internal: return std::unique_ptr<Filter>

This commit is contained in:
Max Kellermann 2017-12-27 11:42:14 +01:00
parent e2621d5e44
commit edef62df86
12 changed files with 64 additions and 70 deletions

View File

@ -27,8 +27,9 @@
#include "AudioFormat.hxx" #include "AudioFormat.hxx"
#include <memory>
#include <assert.h> #include <assert.h>
#include <stddef.h>
struct AudioFormat; struct AudioFormat;
template<typename T> struct ConstBuffer; template<typename T> struct ConstBuffer;
@ -84,7 +85,7 @@ public:
* plugin may modify the object to enforce another input * plugin may modify the object to enforce another input
* format * format
*/ */
virtual Filter *Open(AudioFormat &af) = 0; virtual std::unique_ptr<Filter> Open(AudioFormat &af) = 0;
}; };
#endif #endif

View File

@ -50,26 +50,25 @@ public:
Filter *Get(); Filter *Get();
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
class FilterObserver::Proxy final : public Filter { class FilterObserver::Proxy final : public Filter {
PreparedProxy &parent; PreparedProxy &parent;
Filter *const filter; std::unique_ptr<Filter> filter;
public: public:
Proxy(PreparedProxy &_parent, Filter *_filter) Proxy(PreparedProxy &_parent, std::unique_ptr<Filter> _filter)
:Filter(_filter->GetOutAudioFormat()), :Filter(_filter->GetOutAudioFormat()),
parent(_parent), filter(_filter) {} parent(_parent), filter(std::move(_filter)) {}
~Proxy() { ~Proxy() {
parent.Clear(this); parent.Clear(this);
delete filter;
} }
Filter *Get() { Filter *Get() {
return filter; return filter.get();
} }
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override { ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override {
@ -85,13 +84,14 @@ FilterObserver::PreparedProxy::Get()
: nullptr; : nullptr;
} }
Filter * std::unique_ptr<Filter>
FilterObserver::PreparedProxy::Open(AudioFormat &af) FilterObserver::PreparedProxy::Open(AudioFormat &af)
{ {
assert(child == nullptr); assert(child == nullptr);
Filter *f = prepared_filter->Open(af); auto c = std::make_unique<Proxy>(*this, prepared_filter->Open(af));
return child = new Proxy(*this, f); child = c.get();
return c;
} }
std::unique_ptr<PreparedFilter> std::unique_ptr<PreparedFilter>

View File

@ -68,10 +68,10 @@ public:
PreparedAutoConvertFilter(std::unique_ptr<PreparedFilter> _filter) noexcept PreparedAutoConvertFilter(std::unique_ptr<PreparedFilter> _filter) noexcept
:filter(std::move(_filter)) {} :filter(std::move(_filter)) {}
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
Filter * std::unique_ptr<Filter>
PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format) PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format)
{ {
assert(in_audio_format.IsValid()); assert(in_audio_format.IsValid());
@ -79,7 +79,7 @@ PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format)
/* open the "real" filter */ /* open the "real" filter */
AudioFormat child_audio_format = in_audio_format; AudioFormat child_audio_format = in_audio_format;
std::unique_ptr<Filter> new_filter(filter->Open(child_audio_format)); auto new_filter = filter->Open(child_audio_format);
/* need to convert? */ /* need to convert? */
@ -91,8 +91,8 @@ PreparedAutoConvertFilter::Open(AudioFormat &in_audio_format)
child_audio_format)); child_audio_format));
} }
return new AutoConvertFilter(std::move(new_filter), return std::make_unique<AutoConvertFilter>(std::move(new_filter),
std::move(convert)); std::move(convert));
} }
ConstBuffer<void> ConstBuffer<void>

View File

@ -33,16 +33,10 @@
class ChainFilter final : public Filter { class ChainFilter final : public Filter {
struct Child { struct Child {
const char *name; const char *name;
Filter *filter; std::unique_ptr<Filter> filter;
Child(const char *_name, Filter *_filter) Child(const char *_name, std::unique_ptr<Filter> _filter)
:name(_name), filter(_filter) {} :name(_name), filter(std::move(_filter)) {}
~Child() {
delete filter;
}
Child(const Child &) = delete;
Child &operator=(const Child &) = delete;
}; };
std::list<Child> children; std::list<Child> children;
@ -51,12 +45,12 @@ public:
explicit ChainFilter(AudioFormat _audio_format) explicit ChainFilter(AudioFormat _audio_format)
:Filter(_audio_format) {} :Filter(_audio_format) {}
void Append(const char *name, Filter *filter) { void Append(const char *name, std::unique_ptr<Filter> filter) {
assert(out_audio_format.IsValid()); assert(out_audio_format.IsValid());
out_audio_format = filter->GetOutAudioFormat(); out_audio_format = filter->GetOutAudioFormat();
assert(out_audio_format.IsValid()); assert(out_audio_format.IsValid());
children.emplace_back(name, filter); children.emplace_back(name, std::move(filter));
} }
/* virtual methods from class Filter */ /* virtual methods from class Filter */
@ -76,7 +70,7 @@ class PreparedChainFilter final : public PreparedFilter {
Child(const Child &) = delete; Child(const Child &) = delete;
Child &operator=(const Child &) = delete; Child &operator=(const Child &) = delete;
Filter *Open(const AudioFormat &prev_audio_format); std::unique_ptr<Filter> Open(const AudioFormat &prev_audio_format);
}; };
std::list<Child> children; std::list<Child> children;
@ -88,38 +82,34 @@ public:
} }
/* virtual methods from class PreparedFilter */ /* virtual methods from class PreparedFilter */
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
Filter * std::unique_ptr<Filter>
PreparedChainFilter::Child::Open(const AudioFormat &prev_audio_format) PreparedChainFilter::Child::Open(const AudioFormat &prev_audio_format)
{ {
AudioFormat conv_audio_format = prev_audio_format; AudioFormat conv_audio_format = prev_audio_format;
Filter *new_filter = filter->Open(conv_audio_format); auto new_filter = filter->Open(conv_audio_format);
if (conv_audio_format != prev_audio_format) {
delete new_filter;
if (conv_audio_format != prev_audio_format)
throw FormatRuntimeError("Audio format not supported by filter '%s': %s", throw FormatRuntimeError("Audio format not supported by filter '%s': %s",
name, name,
ToString(prev_audio_format).c_str()); ToString(prev_audio_format).c_str());
}
return new_filter; return new_filter;
} }
Filter * std::unique_ptr<Filter>
PreparedChainFilter::Open(AudioFormat &in_audio_format) PreparedChainFilter::Open(AudioFormat &in_audio_format)
{ {
std::unique_ptr<ChainFilter> chain(new ChainFilter(in_audio_format)); auto chain = std::make_unique<ChainFilter>(in_audio_format);
for (auto &child : children) { for (auto &child : children) {
AudioFormat audio_format = chain->GetOutAudioFormat(); AudioFormat audio_format = chain->GetOutAudioFormat();
auto *filter = child.Open(audio_format); chain->Append(child.name, child.Open(audio_format));
chain->Append(child.name, filter);
} }
return chain.release(); return chain;
} }
void void

View File

@ -59,7 +59,7 @@ public:
class PreparedConvertFilter final : public PreparedFilter { class PreparedConvertFilter final : public PreparedFilter {
public: public:
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
void void
@ -91,12 +91,12 @@ ConvertFilter::ConvertFilter(const AudioFormat &audio_format)
{ {
} }
Filter * std::unique_ptr<Filter>
PreparedConvertFilter::Open(AudioFormat &audio_format) PreparedConvertFilter::Open(AudioFormat &audio_format)
{ {
assert(audio_format.IsValid()); assert(audio_format.IsValid());
return new ConvertFilter(audio_format); return std::make_unique<ConvertFilter>(audio_format);
} }
ConvertFilter::~ConvertFilter() ConvertFilter::~ConvertFilter()

View File

@ -50,7 +50,7 @@ public:
class PreparedNormalizeFilter final : public PreparedFilter { class PreparedNormalizeFilter final : public PreparedFilter {
public: public:
/* virtual methods from class PreparedFilter */ /* virtual methods from class PreparedFilter */
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
static std::unique_ptr<PreparedFilter> static std::unique_ptr<PreparedFilter>
@ -59,12 +59,12 @@ normalize_filter_init(gcc_unused const ConfigBlock &block)
return std::make_unique<PreparedNormalizeFilter>(); return std::make_unique<PreparedNormalizeFilter>();
} }
Filter * std::unique_ptr<Filter>
PreparedNormalizeFilter::Open(AudioFormat &audio_format) PreparedNormalizeFilter::Open(AudioFormat &audio_format)
{ {
audio_format.format = SampleFormat::S16; audio_format.format = SampleFormat::S16;
return new NormalizeFilter(audio_format); return std::make_unique<NormalizeFilter>(audio_format);
} }
ConstBuffer<void> ConstBuffer<void>

View File

@ -43,8 +43,8 @@ public:
class PreparedNullFilter final : public PreparedFilter { class PreparedNullFilter final : public PreparedFilter {
public: public:
virtual Filter *Open(AudioFormat &af) override { virtual std::unique_ptr<Filter> Open(AudioFormat &af) override {
return new NullFilter(af); return std::make_unique<NullFilter>(af);
} }
}; };

View File

@ -138,7 +138,7 @@ public:
} }
/* virtual methods from class Filter */ /* virtual methods from class Filter */
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
void void
@ -177,10 +177,10 @@ NewReplayGainFilter(const ReplayGainConfig &config) noexcept
return std::make_unique<PreparedReplayGainFilter>(config); return std::make_unique<PreparedReplayGainFilter>(config);
} }
Filter * std::unique_ptr<Filter>
PreparedReplayGainFilter::Open(AudioFormat &af) PreparedReplayGainFilter::Open(AudioFormat &af)
{ {
return new ReplayGainFilter(config, af, mixer, base); return std::make_unique<ReplayGainFilter>(config, af, mixer, base);
} }
ConstBuffer<void> ConstBuffer<void>

View File

@ -134,7 +134,7 @@ public:
PreparedRouteFilter(const ConfigBlock &block); PreparedRouteFilter(const ConfigBlock &block);
/* virtual methods from class PreparedFilter */ /* virtual methods from class PreparedFilter */
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
PreparedRouteFilter::PreparedRouteFilter(const ConfigBlock &block) PreparedRouteFilter::PreparedRouteFilter(const ConfigBlock &block)
@ -216,10 +216,11 @@ RouteFilter::RouteFilter(const AudioFormat &audio_format,
output_frame_size = out_audio_format.GetFrameSize(); output_frame_size = out_audio_format.GetFrameSize();
} }
Filter * std::unique_ptr<Filter>
PreparedRouteFilter::Open(AudioFormat &audio_format) PreparedRouteFilter::Open(AudioFormat &audio_format)
{ {
return new RouteFilter(audio_format, min_output_channels, sources); return std::make_unique<RouteFilter>(audio_format, min_output_channels,
sources);
} }
ConstBuffer<void> ConstBuffer<void>

View File

@ -50,13 +50,13 @@ public:
class PreparedVolumeFilter final : public PreparedFilter { class PreparedVolumeFilter final : public PreparedFilter {
public: public:
/* virtual methods from class Filter */ /* virtual methods from class Filter */
Filter *Open(AudioFormat &af) override; std::unique_ptr<Filter> Open(AudioFormat &af) override;
}; };
Filter * std::unique_ptr<Filter>
PreparedVolumeFilter::Open(AudioFormat &audio_format) PreparedVolumeFilter::Open(AudioFormat &audio_format)
{ {
return new VolumeFilter(audio_format); return std::make_unique<VolumeFilter>(audio_format);
} }
ConstBuffer<void> ConstBuffer<void>

View File

@ -29,6 +29,9 @@
#include <string.h> #include <string.h>
AudioOutputSource::AudioOutputSource() noexcept {}
AudioOutputSource::~AudioOutputSource() noexcept = default;
AudioFormat AudioFormat
AudioOutputSource::Open(const AudioFormat audio_format, const MusicPipe &_pipe, AudioOutputSource::Open(const AudioFormat audio_format, const MusicPipe &_pipe,
PreparedFilter *prepared_replay_gain_filter, PreparedFilter *prepared_replay_gain_filter,
@ -116,14 +119,9 @@ try {
void void
AudioOutputSource::CloseFilter() noexcept AudioOutputSource::CloseFilter() noexcept
{ {
delete replay_gain_filter_instance; replay_gain_filter_instance.reset();
replay_gain_filter_instance = nullptr; other_replay_gain_filter_instance.reset();
filter_instance.reset();
delete other_replay_gain_filter_instance;
other_replay_gain_filter_instance = nullptr;
delete filter_instance;
filter_instance = nullptr;
} }
ConstBuffer<void> ConstBuffer<void>
@ -160,7 +158,7 @@ AudioOutputSource::GetChunkData(const MusicChunk &chunk,
ConstBuffer<void> ConstBuffer<void>
AudioOutputSource::FilterChunk(const MusicChunk &chunk) AudioOutputSource::FilterChunk(const MusicChunk &chunk)
{ {
auto data = GetChunkData(chunk, replay_gain_filter_instance, auto data = GetChunkData(chunk, replay_gain_filter_instance.get(),
&replay_gain_serial); &replay_gain_serial);
if (data.empty()) if (data.empty())
return data; return data;
@ -169,7 +167,7 @@ AudioOutputSource::FilterChunk(const MusicChunk &chunk)
if (chunk.other != nullptr) { if (chunk.other != nullptr) {
auto other_data = GetChunkData(*chunk.other, auto other_data = GetChunkData(*chunk.other,
other_replay_gain_filter_instance, other_replay_gain_filter_instance.get(),
&other_replay_gain_serial); &other_replay_gain_serial);
if (other_data.empty()) if (other_data.empty())
return data; return data;

View File

@ -30,6 +30,7 @@
#include "util/ConstBuffer.hxx" #include "util/ConstBuffer.hxx"
#include <utility> #include <utility>
#include <memory>
#include <assert.h> #include <assert.h>
#include <stdint.h> #include <stdint.h>
@ -76,14 +77,14 @@ class AudioOutputSource {
* The replay_gain_filter_plugin instance of this audio * The replay_gain_filter_plugin instance of this audio
* output. * output.
*/ */
Filter *replay_gain_filter_instance = nullptr; std::unique_ptr<Filter> replay_gain_filter_instance;
/** /**
* The replay_gain_filter_plugin instance of this audio * The replay_gain_filter_plugin instance of this audio
* output, to be applied to the second chunk during * output, to be applied to the second chunk during
* cross-fading. * cross-fading.
*/ */
Filter *other_replay_gain_filter_instance = nullptr; std::unique_ptr<Filter> other_replay_gain_filter_instance;
/** /**
* The buffer used to allocate the cross-fading result. * The buffer used to allocate the cross-fading result.
@ -99,7 +100,7 @@ class AudioOutputSource {
* The filter object of this audio output. This is an * The filter object of this audio output. This is an
* instance of chain_filter_plugin. * instance of chain_filter_plugin.
*/ */
Filter *filter_instance = nullptr; std::unique_ptr<Filter> filter_instance;
/** /**
* The #MusicChunk currently being processed (see * The #MusicChunk currently being processed (see
@ -119,6 +120,9 @@ class AudioOutputSource {
ConstBuffer<uint8_t> pending_data; ConstBuffer<uint8_t> pending_data;
public: public:
AudioOutputSource() noexcept;
~AudioOutputSource() noexcept;
void SetReplayGainMode(ReplayGainMode _mode) noexcept { void SetReplayGainMode(ReplayGainMode _mode) noexcept {
replay_gain_mode = _mode; replay_gain_mode = _mode;
} }