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:
parent
00b04468dc
commit
e78d825059
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -18,6 +18,7 @@
|
||||
*/
|
||||
|
||||
#include "ConfigGlue.hxx"
|
||||
#include "pcm/PcmConvert.hxx"
|
||||
#include "lib/chromaprint/DecoderClient.hxx"
|
||||
#include "event/Thread.hxx"
|
||||
#include "decoder/DecoderList.hxx"
|
||||
|
@ -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());
|
||||
|
Loading…
Reference in New Issue
Block a user