pcm/PcmConvert: eliminate Open() and Close()

Let the constructor and destructor do this.  This means that all users
have to be converted to allocate PcmConvert dynamically.
This commit is contained in:
Max Kellermann 2019-04-04 20:55:39 +02:00
parent 00b04468dc
commit e78d825059
9 changed files with 53 additions and 99 deletions

View File

@ -37,15 +37,16 @@
#include <string.h>
#include <math.h>
DecoderBridge::DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
std::unique_ptr<Tag> _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<PcmConvert>(dc.in_audio_format,
dc.out_audio_format);
} catch (...) {
error = std::current_exception();
}

View File

@ -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<PcmConvert> 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> _tag)
:dc(_dc),
initial_seek_pending(_initial_seek_pending),
song_tag(std::move(_tag)) {}
std::unique_ptr<Tag> _tag) noexcept;
~DecoderBridge();

View File

@ -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<PcmConvert> 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<void> FilterPCM(ConstBuffer<void> src) override;
ConstBuffer<void> 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<PcmConvert>(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<ConvertFilter>(audio_format);
}
ConvertFilter::~ConvertFilter()
{
if (IsActive())
state.Close();
}
ConstBuffer<void>
ConvertFilter::FilterPCM(ConstBuffer<void> src)
{
return IsActive()
? state.Convert(src)
return state
? state->Convert(src)
/* optimized special case: no-op */
: src;
}

View File

@ -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<int16_t>::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<PcmConvert>(src_audio_format,
audio_format);
}
chromaprint.Start(audio_format.sample_rate, audio_format.channels);
@ -70,8 +74,8 @@ ChromaprintDecoderClient::SubmitData(InputStream *,
ConstBuffer<void> src{_data, length};
ConstBuffer<int16_t> data;
if (need_convert) {
auto result = convert.Convert(src);
if (convert) {
auto result = convert->Convert(src);
data = ConstBuffer<int16_t>::FromVoid(result);
} else
data = ConstBuffer<int16_t>::FromVoid(src);

View File

@ -22,17 +22,18 @@
#include "Context.hxx"
#include "decoder/Client.hxx"
#include "pcm/PcmConvert.hxx"
#include "thread/Mutex.hxx"
#include <memory>
#include <stdint.h>
class PcmConvert;
class ChromaprintDecoderClient : public DecoderClient {
bool ready = false;
bool need_convert = false;
PcmConvert convert;
std::unique_ptr<PcmConvert> 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();

View File

@ -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

View File

@ -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.
*/

View File

@ -18,6 +18,7 @@
*/
#include "ConfigGlue.hxx"
#include "pcm/PcmConvert.hxx"
#include "lib/chromaprint/DecoderClient.hxx"
#include "event/Thread.hxx"
#include "decoder/DecoderList.hxx"

View File

@ -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<uint8_t, 4096> buffer;
@ -94,8 +93,6 @@ try {
output.size);
}
state.Close();
return EXIT_SUCCESS;
} catch (...) {
PrintException(std::current_exception());