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 <string.h>
|
||||||
#include <math.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()
|
DecoderBridge::~DecoderBridge()
|
||||||
{
|
{
|
||||||
/* caller must flush the chunk */
|
/* caller must flush the chunk */
|
||||||
assert(current_chunk == nullptr);
|
assert(current_chunk == nullptr);
|
||||||
|
|
||||||
if (convert != nullptr) {
|
|
||||||
convert->Close();
|
|
||||||
delete convert;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -255,11 +256,9 @@ DecoderBridge::Ready(const AudioFormat audio_format,
|
|||||||
FormatDebug(decoder_domain, "converting to %s",
|
FormatDebug(decoder_domain, "converting to %s",
|
||||||
ToString(dc.out_audio_format).c_str());
|
ToString(dc.out_audio_format).c_str());
|
||||||
|
|
||||||
convert = new PcmConvert();
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
convert->Open(dc.in_audio_format,
|
convert = std::make_unique<PcmConvert>(dc.in_audio_format,
|
||||||
dc.out_audio_format);
|
dc.out_audio_format);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
error = std::current_exception();
|
error = std::current_exception();
|
||||||
}
|
}
|
||||||
|
@ -44,7 +44,7 @@ public:
|
|||||||
* For converting input data to the configured audio format.
|
* For converting input data to the configured audio format.
|
||||||
* nullptr means no conversion necessary.
|
* nullptr means no conversion necessary.
|
||||||
*/
|
*/
|
||||||
PcmConvert *convert = nullptr;
|
std::unique_ptr<PcmConvert> convert;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The time stamp of the next data chunk, in seconds.
|
* The time stamp of the next data chunk, in seconds.
|
||||||
@ -107,10 +107,7 @@ public:
|
|||||||
std::exception_ptr error;
|
std::exception_ptr error;
|
||||||
|
|
||||||
DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
|
DecoderBridge(DecoderControl &_dc, bool _initial_seek_pending,
|
||||||
std::unique_ptr<Tag> _tag)
|
std::unique_ptr<Tag> _tag) noexcept;
|
||||||
:dc(_dc),
|
|
||||||
initial_seek_pending(_initial_seek_pending),
|
|
||||||
song_tag(std::move(_tag)) {}
|
|
||||||
|
|
||||||
~DecoderBridge();
|
~DecoderBridge();
|
||||||
|
|
||||||
|
@ -41,31 +41,25 @@ class ConvertFilter final : public Filter {
|
|||||||
* This object is only "open" if #in_audio_format !=
|
* This object is only "open" if #in_audio_format !=
|
||||||
* #out_audio_format.
|
* #out_audio_format.
|
||||||
*/
|
*/
|
||||||
PcmConvert state;
|
std::unique_ptr<PcmConvert> state;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ConvertFilter(const AudioFormat &audio_format);
|
ConvertFilter(const AudioFormat &audio_format);
|
||||||
~ConvertFilter();
|
|
||||||
|
|
||||||
void Set(const AudioFormat &_out_audio_format);
|
void Set(const AudioFormat &_out_audio_format);
|
||||||
|
|
||||||
void Reset() noexcept override {
|
void Reset() noexcept override {
|
||||||
if (IsActive())
|
if (state)
|
||||||
state.Reset();
|
state->Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
ConstBuffer<void> FilterPCM(ConstBuffer<void> src) override;
|
||||||
|
|
||||||
ConstBuffer<void> Flush() override {
|
ConstBuffer<void> Flush() override {
|
||||||
return IsActive()
|
return state
|
||||||
? state.Flush()
|
? state->Flush()
|
||||||
: nullptr;
|
: nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
bool IsActive() const noexcept {
|
|
||||||
return out_audio_format != in_audio_format;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class PreparedConvertFilter final : public PreparedFilter {
|
class PreparedConvertFilter final : public PreparedFilter {
|
||||||
@ -82,16 +76,17 @@ ConvertFilter::Set(const AudioFormat &_out_audio_format)
|
|||||||
/* no change */
|
/* no change */
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (IsActive()) {
|
if (state) {
|
||||||
out_audio_format = in_audio_format;
|
out_audio_format = in_audio_format;
|
||||||
state.Close();
|
state.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_out_audio_format == in_audio_format)
|
if (_out_audio_format == in_audio_format)
|
||||||
/* optimized special case: no-op */
|
/* optimized special case: no-op */
|
||||||
return;
|
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;
|
out_audio_format = _out_audio_format;
|
||||||
}
|
}
|
||||||
@ -110,17 +105,11 @@ PreparedConvertFilter::Open(AudioFormat &audio_format)
|
|||||||
return std::make_unique<ConvertFilter>(audio_format);
|
return std::make_unique<ConvertFilter>(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
ConvertFilter::~ConvertFilter()
|
|
||||||
{
|
|
||||||
if (IsActive())
|
|
||||||
state.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
ConstBuffer<void>
|
ConstBuffer<void>
|
||||||
ConvertFilter::FilterPCM(ConstBuffer<void> src)
|
ConvertFilter::FilterPCM(ConstBuffer<void> src)
|
||||||
{
|
{
|
||||||
return IsActive()
|
return state
|
||||||
? state.Convert(src)
|
? state->Convert(src)
|
||||||
/* optimized special case: no-op */
|
/* optimized special case: no-op */
|
||||||
: src;
|
: src;
|
||||||
}
|
}
|
||||||
|
@ -18,17 +18,21 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "DecoderClient.hxx"
|
#include "DecoderClient.hxx"
|
||||||
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "input/InputStream.hxx"
|
#include "input/InputStream.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
|
|
||||||
|
ChromaprintDecoderClient::ChromaprintDecoderClient() = default;
|
||||||
|
ChromaprintDecoderClient::~ChromaprintDecoderClient() noexcept = default;
|
||||||
|
|
||||||
void
|
void
|
||||||
ChromaprintDecoderClient::PrintResult()
|
ChromaprintDecoderClient::PrintResult()
|
||||||
{
|
{
|
||||||
if (!ready)
|
if (!ready)
|
||||||
throw std::runtime_error("Decoding failed");
|
throw std::runtime_error("Decoding failed");
|
||||||
|
|
||||||
if (need_convert) {
|
if (convert) {
|
||||||
auto flushed = convert.Flush();
|
auto flushed = convert->Flush();
|
||||||
auto data = ConstBuffer<int16_t>::FromVoid(flushed);
|
auto data = ConstBuffer<int16_t>::FromVoid(flushed);
|
||||||
chromaprint.Feed(data.data, data.size);
|
chromaprint.Feed(data.data, data.size);
|
||||||
}
|
}
|
||||||
@ -48,8 +52,8 @@ ChromaprintDecoderClient::Ready(AudioFormat audio_format, bool, SignedSongTime)
|
|||||||
const AudioFormat src_audio_format = audio_format;
|
const AudioFormat src_audio_format = audio_format;
|
||||||
audio_format.format = SampleFormat::S16;
|
audio_format.format = SampleFormat::S16;
|
||||||
|
|
||||||
convert.Open(src_audio_format, audio_format);
|
convert = std::make_unique<PcmConvert>(src_audio_format,
|
||||||
need_convert = true;
|
audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
chromaprint.Start(audio_format.sample_rate, audio_format.channels);
|
chromaprint.Start(audio_format.sample_rate, audio_format.channels);
|
||||||
@ -70,8 +74,8 @@ ChromaprintDecoderClient::SubmitData(InputStream *,
|
|||||||
ConstBuffer<void> src{_data, length};
|
ConstBuffer<void> src{_data, length};
|
||||||
ConstBuffer<int16_t> data;
|
ConstBuffer<int16_t> data;
|
||||||
|
|
||||||
if (need_convert) {
|
if (convert) {
|
||||||
auto result = convert.Convert(src);
|
auto result = convert->Convert(src);
|
||||||
data = ConstBuffer<int16_t>::FromVoid(result);
|
data = ConstBuffer<int16_t>::FromVoid(result);
|
||||||
} else
|
} else
|
||||||
data = ConstBuffer<int16_t>::FromVoid(src);
|
data = ConstBuffer<int16_t>::FromVoid(src);
|
||||||
|
@ -22,17 +22,18 @@
|
|||||||
|
|
||||||
#include "Context.hxx"
|
#include "Context.hxx"
|
||||||
#include "decoder/Client.hxx"
|
#include "decoder/Client.hxx"
|
||||||
#include "pcm/PcmConvert.hxx"
|
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
class PcmConvert;
|
||||||
|
|
||||||
class ChromaprintDecoderClient : public DecoderClient {
|
class ChromaprintDecoderClient : public DecoderClient {
|
||||||
bool ready = false;
|
bool ready = false;
|
||||||
|
|
||||||
bool need_convert = false;
|
std::unique_ptr<PcmConvert> convert;
|
||||||
|
|
||||||
PcmConvert convert;
|
|
||||||
|
|
||||||
Chromaprint::Context chromaprint;
|
Chromaprint::Context chromaprint;
|
||||||
|
|
||||||
@ -41,10 +42,8 @@ class ChromaprintDecoderClient : public DecoderClient {
|
|||||||
public:
|
public:
|
||||||
Mutex mutex;
|
Mutex mutex;
|
||||||
|
|
||||||
~ChromaprintDecoderClient() noexcept {
|
ChromaprintDecoderClient();
|
||||||
if (need_convert)
|
~ChromaprintDecoderClient() noexcept;
|
||||||
convert.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintResult();
|
void PrintResult();
|
||||||
|
|
||||||
|
@ -29,27 +29,12 @@ pcm_convert_global_init(const ConfigData &config)
|
|||||||
pcm_resampler_global_init(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
|
assert(src_format.IsValid());
|
||||||
src_format.Clear();
|
assert(dest_format.IsValid());
|
||||||
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());
|
|
||||||
|
|
||||||
AudioFormat format = _src_format;
|
AudioFormat format = _src_format;
|
||||||
if (format.format == SampleFormat::DSD)
|
if (format.format == SampleFormat::DSD)
|
||||||
@ -90,13 +75,9 @@ PcmConvert::Open(const AudioFormat _src_format, const AudioFormat _dest_format)
|
|||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
src_format = _src_format;
|
|
||||||
dest_format = _dest_format;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
PcmConvert::~PcmConvert() noexcept
|
||||||
PcmConvert::Close() noexcept
|
|
||||||
{
|
{
|
||||||
if (enable_channels)
|
if (enable_channels)
|
||||||
channels_converter.Close();
|
channels_converter.Close();
|
||||||
@ -108,11 +89,6 @@ PcmConvert::Close() noexcept
|
|||||||
#ifdef ENABLE_DSD
|
#ifdef ENABLE_DSD
|
||||||
dsd.Reset();
|
dsd.Reset();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef NDEBUG
|
|
||||||
src_format.Clear();
|
|
||||||
dest_format.Clear();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -47,27 +47,19 @@ class PcmConvert {
|
|||||||
PcmFormatConverter format_converter;
|
PcmFormatConverter format_converter;
|
||||||
PcmChannelsConverter channels_converter;
|
PcmChannelsConverter channels_converter;
|
||||||
|
|
||||||
AudioFormat src_format, dest_format;
|
const AudioFormat src_format, dest_format;
|
||||||
|
|
||||||
bool enable_resampler, enable_format, enable_channels;
|
bool enable_resampler, enable_format, enable_channels;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PcmConvert() noexcept;
|
|
||||||
|
/**
|
||||||
|
* Throws on error.
|
||||||
|
*/
|
||||||
|
PcmConvert(AudioFormat _src_format, AudioFormat _dest_format);
|
||||||
|
|
||||||
~PcmConvert() noexcept;
|
~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.
|
* Reset the filter's state, e.g. drop/flush buffers.
|
||||||
*/
|
*/
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ConfigGlue.hxx"
|
#include "ConfigGlue.hxx"
|
||||||
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "lib/chromaprint/DecoderClient.hxx"
|
#include "lib/chromaprint/DecoderClient.hxx"
|
||||||
#include "event/Thread.hxx"
|
#include "event/Thread.hxx"
|
||||||
#include "decoder/DecoderList.hxx"
|
#include "decoder/DecoderList.hxx"
|
||||||
|
@ -53,8 +53,7 @@ try {
|
|||||||
|
|
||||||
const size_t in_frame_size = in_audio_format.GetFrameSize();
|
const size_t in_frame_size = in_audio_format.GetFrameSize();
|
||||||
|
|
||||||
PcmConvert state;
|
PcmConvert state(in_audio_format, out_audio_format);
|
||||||
state.Open(in_audio_format, out_audio_format);
|
|
||||||
|
|
||||||
StaticFifoBuffer<uint8_t, 4096> buffer;
|
StaticFifoBuffer<uint8_t, 4096> buffer;
|
||||||
|
|
||||||
@ -94,8 +93,6 @@ try {
|
|||||||
output.size);
|
output.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
state.Close();
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
return EXIT_SUCCESS;
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
PrintException(std::current_exception());
|
PrintException(std::current_exception());
|
||||||
|
Loading…
Reference in New Issue
Block a user