output/fifo: use template AudioOutputWrapper
This commit is contained in:
parent
593bb5a8a7
commit
8bfb88840b
@ -21,6 +21,7 @@
|
|||||||
#include "FifoOutputPlugin.hxx"
|
#include "FifoOutputPlugin.hxx"
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Wrapper.hxx"
|
||||||
#include "../Timer.hxx"
|
#include "../Timer.hxx"
|
||||||
#include "fs/AllocatedPath.hxx"
|
#include "fs/AllocatedPath.hxx"
|
||||||
#include "fs/FileSystem.hxx"
|
#include "fs/FileSystem.hxx"
|
||||||
@ -51,16 +52,26 @@ struct FifoOutput {
|
|||||||
path(AllocatedPath::Null()), input(-1), output(-1),
|
path(AllocatedPath::Null()), input(-1), output(-1),
|
||||||
created(false) {}
|
created(false) {}
|
||||||
|
|
||||||
|
~FifoOutput() {
|
||||||
|
Close();
|
||||||
|
}
|
||||||
|
|
||||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||||
return base.Configure(block, error);
|
return base.Configure(block, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static FifoOutput *Create(const ConfigBlock &block, Error &error);
|
||||||
|
|
||||||
bool Create(Error &error);
|
bool Create(Error &error);
|
||||||
bool Check(Error &error);
|
bool Check(Error &error);
|
||||||
void Delete();
|
void Delete();
|
||||||
|
|
||||||
bool Open(Error &error);
|
bool Open(Error &error);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
|
unsigned Delay() const;
|
||||||
|
size_t Play(const void *chunk, size_t size, Error &error);
|
||||||
|
void Cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr Domain fifo_output_domain("fifo_output");
|
static constexpr Domain fifo_output_domain("fifo_output");
|
||||||
@ -162,14 +173,8 @@ FifoOutput::Open(Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
inline FifoOutput *
|
||||||
fifo_open(FifoOutput *fd, Error &error)
|
FifoOutput::Create(const ConfigBlock &block, Error &error)
|
||||||
{
|
|
||||||
return fd->Open(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static AudioOutput *
|
|
||||||
fifo_output_init(const ConfigBlock &block, Error &error)
|
|
||||||
{
|
{
|
||||||
FifoOutput *fd = new FifoOutput();
|
FifoOutput *fd = new FifoOutput();
|
||||||
|
|
||||||
@ -190,21 +195,12 @@ fifo_output_init(const ConfigBlock &block, Error &error)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fifo_open(fd, error)) {
|
if (!fd->Open(error)) {
|
||||||
delete fd;
|
delete fd;
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &fd->base;
|
return fd;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
fifo_output_finish(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
FifoOutput *fd = (FifoOutput *)ao;
|
|
||||||
|
|
||||||
fd->Close();
|
|
||||||
delete fd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -226,47 +222,41 @@ fifo_output_close(AudioOutput *ao)
|
|||||||
delete fd->timer;
|
delete fd->timer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
inline void
|
||||||
fifo_output_cancel(AudioOutput *ao)
|
FifoOutput::Cancel()
|
||||||
{
|
{
|
||||||
FifoOutput *fd = (FifoOutput *)ao;
|
|
||||||
char buf[FIFO_BUFFER_SIZE];
|
char buf[FIFO_BUFFER_SIZE];
|
||||||
int bytes = 1;
|
int bytes = 1;
|
||||||
|
|
||||||
fd->timer->Reset();
|
timer->Reset();
|
||||||
|
|
||||||
while (bytes > 0 && errno != EINTR)
|
while (bytes > 0 && errno != EINTR)
|
||||||
bytes = read(fd->input, buf, FIFO_BUFFER_SIZE);
|
bytes = read(input, buf, FIFO_BUFFER_SIZE);
|
||||||
|
|
||||||
if (bytes < 0 && errno != EAGAIN) {
|
if (bytes < 0 && errno != EAGAIN) {
|
||||||
FormatErrno(fifo_output_domain,
|
FormatErrno(fifo_output_domain,
|
||||||
"Flush of FIFO \"%s\" failed",
|
"Flush of FIFO \"%s\" failed",
|
||||||
fd->path_utf8.c_str());
|
path_utf8.c_str());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static unsigned
|
inline unsigned
|
||||||
fifo_output_delay(AudioOutput *ao)
|
FifoOutput::Delay() const
|
||||||
{
|
{
|
||||||
FifoOutput *fd = (FifoOutput *)ao;
|
return timer->IsStarted()
|
||||||
|
? timer->GetDelay()
|
||||||
return fd->timer->IsStarted()
|
|
||||||
? fd->timer->GetDelay()
|
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
inline size_t
|
||||||
fifo_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
FifoOutput::Play(const void *chunk, size_t size, Error &error)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
FifoOutput *fd = (FifoOutput *)ao;
|
if (!timer->IsStarted())
|
||||||
|
timer->Start();
|
||||||
if (!fd->timer->IsStarted())
|
timer->Add(size);
|
||||||
fd->timer->Start();
|
|
||||||
fd->timer->Add(size);
|
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
ssize_t bytes = write(fd->output, chunk, size);
|
ssize_t bytes = write(output, chunk, size);
|
||||||
if (bytes > 0)
|
if (bytes > 0)
|
||||||
return (size_t)bytes;
|
return (size_t)bytes;
|
||||||
|
|
||||||
@ -274,33 +264,35 @@ fifo_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
|||||||
switch (errno) {
|
switch (errno) {
|
||||||
case EAGAIN:
|
case EAGAIN:
|
||||||
/* The pipe is full, so empty it */
|
/* The pipe is full, so empty it */
|
||||||
fifo_output_cancel(&fd->base);
|
Cancel();
|
||||||
continue;
|
continue;
|
||||||
case EINTR:
|
case EINTR:
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
error.FormatErrno("Failed to write to FIFO %s",
|
error.FormatErrno("Failed to write to FIFO %s",
|
||||||
fd->path_utf8.c_str());
|
path_utf8.c_str());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef AudioOutputWrapper<FifoOutput> Wrapper;
|
||||||
|
|
||||||
const struct AudioOutputPlugin fifo_output_plugin = {
|
const struct AudioOutputPlugin fifo_output_plugin = {
|
||||||
"fifo",
|
"fifo",
|
||||||
nullptr,
|
nullptr,
|
||||||
fifo_output_init,
|
&Wrapper::Init,
|
||||||
fifo_output_finish,
|
&Wrapper::Finish,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
fifo_output_open,
|
fifo_output_open,
|
||||||
fifo_output_close,
|
fifo_output_close,
|
||||||
fifo_output_delay,
|
&Wrapper::Delay,
|
||||||
nullptr,
|
nullptr,
|
||||||
fifo_output_play,
|
&Wrapper::Play,
|
||||||
nullptr,
|
nullptr,
|
||||||
fifo_output_cancel,
|
&Wrapper::Cancel,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user