output/Interface: convert to abstract class
Yet another C-style vtable replaced with C++.
This commit is contained in:
@@ -22,7 +22,6 @@
|
||||
#include "lib/alsa/NonBlock.hxx"
|
||||
#include "lib/alsa/Version.hxx"
|
||||
#include "../OutputAPI.hxx"
|
||||
#include "../Wrapper.hxx"
|
||||
#include "mixer/MixerList.hxx"
|
||||
#include "pcm/PcmExport.hxx"
|
||||
#include "system/ByteOrder.hxx"
|
||||
@@ -60,11 +59,7 @@ static constexpr unsigned MPD_ALSA_BUFFER_TIME_US = 500000;
|
||||
static constexpr unsigned MPD_ALSA_RETRY_NR = 5;
|
||||
|
||||
class AlsaOutput final
|
||||
: MultiSocketMonitor, DeferredMonitor {
|
||||
|
||||
friend struct AudioOutputWrapper<AlsaOutput>;
|
||||
|
||||
AudioOutput base;
|
||||
: AudioOutput, MultiSocketMonitor, DeferredMonitor {
|
||||
|
||||
Manual<PcmExport> pcm_export;
|
||||
|
||||
@@ -290,20 +285,22 @@ public:
|
||||
return device.empty() ? default_device : device.c_str();
|
||||
}
|
||||
|
||||
static AlsaOutput *Create(EventLoop &event_loop,
|
||||
const ConfigBlock &block);
|
||||
|
||||
void Enable();
|
||||
void Disable();
|
||||
|
||||
void Open(AudioFormat &audio_format);
|
||||
void Close();
|
||||
|
||||
size_t Play(const void *chunk, size_t size);
|
||||
void Drain();
|
||||
void Cancel();
|
||||
static AudioOutput *Create(EventLoop &event_loop,
|
||||
const ConfigBlock &block) {
|
||||
return new AlsaOutput(event_loop, block);
|
||||
}
|
||||
|
||||
private:
|
||||
void Enable() override;
|
||||
void Disable() noexcept override;
|
||||
|
||||
void Open(AudioFormat &audio_format) override;
|
||||
void Close() noexcept override;
|
||||
|
||||
size_t Play(const void *chunk, size_t size) override;
|
||||
void Drain() override;
|
||||
void Cancel() noexcept override;
|
||||
|
||||
/**
|
||||
* Set up the snd_pcm_t object which was opened by the caller.
|
||||
* Set up the configured settings and the audio format.
|
||||
@@ -413,8 +410,8 @@ private:
|
||||
static constexpr Domain alsa_output_domain("alsa_output");
|
||||
|
||||
AlsaOutput::AlsaOutput(EventLoop &loop, const ConfigBlock &block)
|
||||
:MultiSocketMonitor(loop), DeferredMonitor(loop),
|
||||
base(alsa_output_plugin),
|
||||
:AudioOutput(FLAG_ENABLE_DISABLE),
|
||||
MultiSocketMonitor(loop), DeferredMonitor(loop),
|
||||
device(block.GetBlockValue("device", "")),
|
||||
#ifdef ENABLE_DSD
|
||||
dop(block.GetBlockValue("dop", false) ||
|
||||
@@ -441,20 +438,14 @@ AlsaOutput::AlsaOutput(EventLoop &loop, const ConfigBlock &block)
|
||||
#endif
|
||||
}
|
||||
|
||||
inline AlsaOutput *
|
||||
AlsaOutput::Create(EventLoop &event_loop, const ConfigBlock &block)
|
||||
{
|
||||
return new AlsaOutput(event_loop, block);
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
AlsaOutput::Enable()
|
||||
{
|
||||
pcm_export.Construct();
|
||||
}
|
||||
|
||||
inline void
|
||||
AlsaOutput::Disable()
|
||||
void
|
||||
AlsaOutput::Disable() noexcept
|
||||
{
|
||||
pcm_export.Destruct();
|
||||
}
|
||||
@@ -1015,7 +1006,7 @@ MaybeDmix(snd_pcm_t *pcm) noexcept
|
||||
return MaybeDmix(snd_pcm_type(pcm));
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
AlsaOutput::Open(AudioFormat &audio_format)
|
||||
{
|
||||
int err = snd_pcm_open(&pcm, GetDevice(),
|
||||
@@ -1158,7 +1149,7 @@ AlsaOutput::DrainInternal()
|
||||
return snd_pcm_drain(pcm) != -EAGAIN;
|
||||
}
|
||||
|
||||
inline void
|
||||
void
|
||||
AlsaOutput::Drain()
|
||||
{
|
||||
const std::lock_guard<Mutex> lock(mutex);
|
||||
@@ -1183,8 +1174,8 @@ AlsaOutput::CancelInternal()
|
||||
ClearRingBuffer();
|
||||
}
|
||||
|
||||
inline void
|
||||
AlsaOutput::Cancel()
|
||||
void
|
||||
AlsaOutput::Cancel() noexcept
|
||||
{
|
||||
if (!active) {
|
||||
/* early cancel, quick code path without thread
|
||||
@@ -1202,8 +1193,8 @@ AlsaOutput::Cancel()
|
||||
});
|
||||
}
|
||||
|
||||
inline void
|
||||
AlsaOutput::Close()
|
||||
void
|
||||
AlsaOutput::Close() noexcept
|
||||
{
|
||||
/* make sure the I/O thread isn't inside DispatchSockets() */
|
||||
BlockingCall(MultiSocketMonitor::GetEventLoop(), [this](){
|
||||
@@ -1217,7 +1208,7 @@ AlsaOutput::Close()
|
||||
delete[] silence;
|
||||
}
|
||||
|
||||
inline size_t
|
||||
size_t
|
||||
AlsaOutput::Play(const void *chunk, size_t size)
|
||||
{
|
||||
assert(size > 0);
|
||||
@@ -1331,23 +1322,9 @@ try {
|
||||
cond.signal();
|
||||
}
|
||||
|
||||
typedef AudioOutputWrapper<AlsaOutput> Wrapper;
|
||||
|
||||
const struct AudioOutputPlugin alsa_output_plugin = {
|
||||
"alsa",
|
||||
alsa_test_default_device,
|
||||
&Wrapper::Init,
|
||||
&Wrapper::Finish,
|
||||
&Wrapper::Enable,
|
||||
&Wrapper::Disable,
|
||||
&Wrapper::Open,
|
||||
&Wrapper::Close,
|
||||
nullptr,
|
||||
nullptr,
|
||||
&Wrapper::Play,
|
||||
&Wrapper::Drain,
|
||||
&Wrapper::Cancel,
|
||||
nullptr,
|
||||
|
||||
&AlsaOutput::Create,
|
||||
&alsa_mixer_plugin,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user