diff --git a/src/decoder/Bridge.cxx b/src/decoder/Bridge.cxx index 59d80cc48..969dbd8b8 100644 --- a/src/decoder/Bridge.cxx +++ b/src/decoder/Bridge.cxx @@ -37,15 +37,16 @@ #include #include +DecoderBridge::DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending, + std::unique_ptr _tag) noexcept + :dc(_dc), + initial_seek_pending(_initial_seek_pending), + song_tag(std::move(_tag)) {} + DecoderBridge::~DecoderBridge() { /* caller must flush the chunk */ assert(current_chunk == nullptr); - - if (convert != nullptr) { - convert->Close(); - delete convert; - } } bool @@ -255,11 +256,9 @@ DecoderBridge::Ready(const AudioFormat audio_format, FormatDebug(decoder_domain, "converting to %s", ToString(dc.out_audio_format).c_str()); - convert = new PcmConvert(); - try { - convert->Open(dc.in_audio_format, - dc.out_audio_format); + convert = std::make_unique(dc.in_audio_format, + dc.out_audio_format); } catch (...) { error = std::current_exception(); } diff --git a/src/decoder/Bridge.hxx b/src/decoder/Bridge.hxx index f94909f31..0077b2b68 100644 --- a/src/decoder/Bridge.hxx +++ b/src/decoder/Bridge.hxx @@ -44,7 +44,7 @@ public: * For converting input data to the configured audio format. * nullptr means no conversion necessary. */ - PcmConvert *convert = nullptr; + std::unique_ptr convert; /** * The time stamp of the next data chunk, in seconds. @@ -107,10 +107,7 @@ public: std::exception_ptr error; DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending, - std::unique_ptr _tag) - :dc(_dc), - initial_seek_pending(_initial_seek_pending), - song_tag(std::move(_tag)) {} + std::unique_ptr _tag) noexcept; ~DecoderBridge(); diff --git a/src/filter/plugins/ConvertFilterPlugin.cxx b/src/filter/plugins/ConvertFilterPlugin.cxx index a5e501afd..8a0a8c7d8 100644 --- a/src/filter/plugins/ConvertFilterPlugin.cxx +++ b/src/filter/plugins/ConvertFilterPlugin.cxx @@ -41,31 +41,25 @@ class ConvertFilter final : public Filter { * This object is only "open" if #in_audio_format != * #out_audio_format. */ - PcmConvert state; + std::unique_ptr state; public: ConvertFilter(const AudioFormat &audio_format); - ~ConvertFilter(); void Set(const AudioFormat &_out_audio_format); void Reset() noexcept override { - if (IsActive()) - state.Reset(); + if (state) + state->Reset(); } ConstBuffer FilterPCM(ConstBuffer src) override; ConstBuffer Flush() override { - return IsActive() - ? state.Flush() + return state + ? state->Flush() : nullptr; } - -private: - bool IsActive() const noexcept { - return out_audio_format != in_audio_format; - } }; class PreparedConvertFilter final : public PreparedFilter { @@ -82,16 +76,17 @@ ConvertFilter::Set(const AudioFormat &_out_audio_format) /* no change */ return; - if (IsActive()) { + if (state) { out_audio_format = in_audio_format; - state.Close(); + state.reset(); } if (_out_audio_format == in_audio_format) /* optimized special case: no-op */ return; - state.Open(in_audio_format, _out_audio_format); + state = std::make_unique(in_audio_format, + _out_audio_format); out_audio_format = _out_audio_format; } @@ -110,17 +105,11 @@ PreparedConvertFilter::Open(AudioFormat &audio_format) return std::make_unique(audio_format); } -ConvertFilter::~ConvertFilter() -{ - if (IsActive()) - state.Close(); -} - ConstBuffer ConvertFilter::FilterPCM(ConstBuffer src) { - return IsActive() - ? state.Convert(src) + return state + ? state->Convert(src) /* optimized special case: no-op */ : src; } diff --git a/src/lib/chromaprint/DecoderClient.cxx b/src/lib/chromaprint/DecoderClient.cxx index f71bea82b..3291a4515 100644 --- a/src/lib/chromaprint/DecoderClient.cxx +++ b/src/lib/chromaprint/DecoderClient.cxx @@ -18,17 +18,21 @@ */ #include "DecoderClient.hxx" +#include "pcm/PcmConvert.hxx" #include "input/InputStream.hxx" #include "util/ConstBuffer.hxx" +ChromaprintDecoderClient::ChromaprintDecoderClient() = default; +ChromaprintDecoderClient::~ChromaprintDecoderClient() noexcept = default; + void ChromaprintDecoderClient::PrintResult() { if (!ready) throw std::runtime_error("Decoding failed"); - if (need_convert) { - auto flushed = convert.Flush(); + if (convert) { + auto flushed = convert->Flush(); auto data = ConstBuffer::FromVoid(flushed); chromaprint.Feed(data.data, data.size); } @@ -48,8 +52,8 @@ ChromaprintDecoderClient::Ready(AudioFormat audio_format, bool, SignedSongTime) const AudioFormat src_audio_format = audio_format; audio_format.format = SampleFormat::S16; - convert.Open(src_audio_format, audio_format); - need_convert = true; + convert = std::make_unique(src_audio_format, + audio_format); } chromaprint.Start(audio_format.sample_rate, audio_format.channels); @@ -70,8 +74,8 @@ ChromaprintDecoderClient::SubmitData(InputStream *, ConstBuffer src{_data, length}; ConstBuffer data; - if (need_convert) { - auto result = convert.Convert(src); + if (convert) { + auto result = convert->Convert(src); data = ConstBuffer::FromVoid(result); } else data = ConstBuffer::FromVoid(src); diff --git a/src/lib/chromaprint/DecoderClient.hxx b/src/lib/chromaprint/DecoderClient.hxx index 956983779..ce4f7245e 100644 --- a/src/lib/chromaprint/DecoderClient.hxx +++ b/src/lib/chromaprint/DecoderClient.hxx @@ -22,17 +22,18 @@ #include "Context.hxx" #include "decoder/Client.hxx" -#include "pcm/PcmConvert.hxx" #include "thread/Mutex.hxx" +#include + #include +class PcmConvert; + class ChromaprintDecoderClient : public DecoderClient { bool ready = false; - bool need_convert = false; - - PcmConvert convert; + std::unique_ptr convert; Chromaprint::Context chromaprint; @@ -41,10 +42,8 @@ class ChromaprintDecoderClient : public DecoderClient { public: Mutex mutex; - ~ChromaprintDecoderClient() noexcept { - if (need_convert) - convert.Close(); - } + ChromaprintDecoderClient(); + ~ChromaprintDecoderClient() noexcept; void PrintResult(); diff --git a/src/pcm/PcmConvert.cxx b/src/pcm/PcmConvert.cxx index dfe7cd204..6e57cf541 100644 --- a/src/pcm/PcmConvert.cxx +++ b/src/pcm/PcmConvert.cxx @@ -29,27 +29,12 @@ pcm_convert_global_init(const ConfigData &config) pcm_resampler_global_init(config); } -PcmConvert::PcmConvert() noexcept +PcmConvert::PcmConvert(const AudioFormat _src_format, + const AudioFormat _dest_format) + :src_format(_src_format), dest_format(_dest_format) { -#ifndef NDEBUG - src_format.Clear(); - dest_format.Clear(); -#endif -} - -PcmConvert::~PcmConvert() noexcept -{ - assert(!src_format.IsValid()); - assert(!dest_format.IsValid()); -} - -void -PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format) -{ - assert(!src_format.IsValid()); - assert(!dest_format.IsValid()); - assert(_src_format.IsValid()); - assert(_dest_format.IsValid()); + assert(src_format.IsValid()); + assert(dest_format.IsValid()); AudioFormat format = _src_format; if (format.format == SampleFormat::DSD) @@ -90,13 +75,9 @@ PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format) throw; } } - - src_format = _src_format; - dest_format = _dest_format; } -void -PcmConvert::Close() noexcept +PcmConvert::~PcmConvert() noexcept { if (enable_channels) channels_converter.Close(); @@ -108,11 +89,6 @@ PcmConvert::Close() noexcept #ifdef ENABLE_DSD dsd.Reset(); #endif - -#ifndef NDEBUG - src_format.Clear(); - dest_format.Clear(); -#endif } void diff --git a/src/pcm/PcmConvert.hxx b/src/pcm/PcmConvert.hxx index 505ccefca..e90accd97 100644 --- a/src/pcm/PcmConvert.hxx +++ b/src/pcm/PcmConvert.hxx @@ -47,27 +47,19 @@ class PcmConvert { PcmFormatConverter format_converter; PcmChannelsConverter channels_converter; - AudioFormat src_format, dest_format; + const AudioFormat src_format, dest_format; bool enable_resampler, enable_format, enable_channels; public: - PcmConvert() noexcept; + + /** + * Throws on error. + */ + PcmConvert(AudioFormat _src_format, AudioFormat _dest_format); + ~PcmConvert() noexcept; - /** - * Prepare the object. Call Close() when done. - * - * Throws std::runtime_error on error. - */ - void Open(AudioFormat _src_format, AudioFormat _dest_format); - - /** - * Close the object after it was prepared with Open(). After - * that, it may be reused by calling Open() again. - */ - void Close() noexcept; - /** * Reset the filter's state, e.g. drop/flush buffers. */ diff --git a/test/RunChromaprint.cxx b/test/RunChromaprint.cxx index cfcfb7f60..710aaeeb8 100644 --- a/test/RunChromaprint.cxx +++ b/test/RunChromaprint.cxx @@ -18,6 +18,7 @@ */ #include "ConfigGlue.hxx" +#include "pcm/PcmConvert.hxx" #include "lib/chromaprint/DecoderClient.hxx" #include "event/Thread.hxx" #include "decoder/DecoderList.hxx" diff --git a/test/run_convert.cxx b/test/run_convert.cxx index 868a483db..c7fe63138 100644 --- a/test/run_convert.cxx +++ b/test/run_convert.cxx @@ -53,8 +53,7 @@ try { const size_t in_frame_size = in_audio_format.GetFrameSize(); - PcmConvert state; - state.Open(in_audio_format, out_audio_format); + PcmConvert state(in_audio_format, out_audio_format); StaticFifoBuffer buffer; @@ -94,8 +93,6 @@ try { output.size); } - state.Close(); - return EXIT_SUCCESS; } catch (...) { PrintException(std::current_exception());