output/Wrapper: new helper class
This commit is contained in:
parent
977834179a
commit
0b9f650fe2
@ -1236,6 +1236,7 @@ OUTPUT_LIBS = \
|
|||||||
OUTPUT_API_SRC = \
|
OUTPUT_API_SRC = \
|
||||||
src/output/OutputAPI.hxx \
|
src/output/OutputAPI.hxx \
|
||||||
src/output/Internal.hxx \
|
src/output/Internal.hxx \
|
||||||
|
src/output/Wrapper.hxx \
|
||||||
src/output/Registry.cxx src/output/Registry.hxx \
|
src/output/Registry.cxx src/output/Registry.hxx \
|
||||||
src/output/MultipleOutputs.cxx src/output/MultipleOutputs.hxx \
|
src/output/MultipleOutputs.cxx src/output/MultipleOutputs.hxx \
|
||||||
src/output/OutputThread.cxx \
|
src/output/OutputThread.cxx \
|
||||||
|
93
src/output/Wrapper.hxx
Normal file
93
src/output/Wrapper.hxx
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2003-2014 The Music Player Daemon Project
|
||||||
|
* http://www.musicpd.org
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along
|
||||||
|
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef MPD_OUTPUT_WRAPPER_HXX
|
||||||
|
#define MPD_OUTPUT_WRAPPER_HXX
|
||||||
|
|
||||||
|
#include "util/Cast.hxx"
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
struct AudioOutputWrapper {
|
||||||
|
static T &Cast(AudioOutput &ao) {
|
||||||
|
return ContainerCast(ao, &T::base);
|
||||||
|
}
|
||||||
|
|
||||||
|
static AudioOutput *Init(const config_param ¶m, Error &error) {
|
||||||
|
T *t = T::Create(param, error);
|
||||||
|
return t != nullptr
|
||||||
|
? &t->base
|
||||||
|
: nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Finish(AudioOutput *ao) {
|
||||||
|
T *t = &Cast(*ao);
|
||||||
|
delete t;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Enable(AudioOutput *ao, Error &error) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
return t.Enable(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Disable(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
t.Disable();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool Open(AudioOutput *ao, AudioFormat &audio_format,
|
||||||
|
Error &error) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
return t.Open(audio_format, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Close(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
t.Close();
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
static unsigned Delay(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
return t.Delay();
|
||||||
|
}
|
||||||
|
|
||||||
|
static size_t Play(AudioOutput *ao, const void *chunk, size_t size,
|
||||||
|
Error &error) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
return t.Play(chunk, size, error);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Drain(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
t.Drain();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void Cancel(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
t.Cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
gcc_pure
|
||||||
|
static bool Pause(AudioOutput *ao) {
|
||||||
|
T &t = Cast(*ao);
|
||||||
|
return t.Pause();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "JackOutputPlugin.hxx"
|
#include "JackOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Wrapper.hxx"
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "util/SplitString.hxx"
|
#include "util/SplitString.hxx"
|
||||||
@ -100,6 +101,10 @@ struct JackOutput {
|
|||||||
|
|
||||||
bool Open(AudioFormat &new_audio_format, Error &error);
|
bool Open(AudioFormat &new_audio_format, Error &error);
|
||||||
|
|
||||||
|
void Close() {
|
||||||
|
Stop();
|
||||||
|
}
|
||||||
|
|
||||||
bool Start(Error &error);
|
bool Start(Error &error);
|
||||||
void Stop();
|
void Stop();
|
||||||
|
|
||||||
@ -117,7 +122,15 @@ struct JackOutput {
|
|||||||
*/
|
*/
|
||||||
size_t WriteSamples(const float *src, size_t n_frames);
|
size_t WriteSamples(const float *src, size_t n_frames);
|
||||||
|
|
||||||
|
unsigned Delay() const {
|
||||||
|
return base.pause && pause && !shutdown
|
||||||
|
? 1000
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size, Error &error);
|
||||||
|
|
||||||
|
bool Pause();
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr Domain jack_output_domain("jack_output");
|
static constexpr Domain jack_output_domain("jack_output");
|
||||||
@ -468,30 +481,6 @@ mpd_jack_init(const config_param ¶m, Error &error)
|
|||||||
return &jd->base;
|
return &jd->base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
mpd_jack_finish(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
JackOutput *jd = (JackOutput *)ao;
|
|
||||||
|
|
||||||
delete jd;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
mpd_jack_enable(AudioOutput *ao, Error &error)
|
|
||||||
{
|
|
||||||
JackOutput &jo = *(JackOutput *)ao;
|
|
||||||
|
|
||||||
return jo.Enable(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mpd_jack_disable(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
JackOutput &jo = *(JackOutput *)ao;
|
|
||||||
|
|
||||||
jo.Disable();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stops the playback on the JACK connection.
|
* Stops the playback on the JACK connection.
|
||||||
*/
|
*/
|
||||||
@ -648,33 +637,6 @@ JackOutput::Open(AudioFormat &new_audio_format, Error &error)
|
|||||||
return Start(error);
|
return Start(error);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
mpd_jack_open(AudioOutput *ao, AudioFormat &audio_format,
|
|
||||||
Error &error)
|
|
||||||
{
|
|
||||||
JackOutput &jo = *(JackOutput *)ao;
|
|
||||||
|
|
||||||
return jo.Open(audio_format, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
mpd_jack_close(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
JackOutput &jo = *(JackOutput *)ao;
|
|
||||||
|
|
||||||
jo.Stop();
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
mpd_jack_delay(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
JackOutput *jd = (JackOutput *)ao;
|
|
||||||
|
|
||||||
return jd->base.pause && jd->pause && !jd->shutdown
|
|
||||||
? 1000
|
|
||||||
: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
JackOutput::WriteSamples(const float *src, size_t n_frames)
|
JackOutput::WriteSamples(const float *src, size_t n_frames)
|
||||||
{
|
{
|
||||||
@ -744,42 +706,33 @@ JackOutput::Play(const void *chunk, size_t size, Error &error)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
inline bool
|
||||||
mpd_jack_play(AudioOutput *ao, const void *chunk, size_t size,
|
JackOutput::Pause()
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
JackOutput &jo = *(JackOutput *)ao;
|
if (shutdown)
|
||||||
|
|
||||||
return jo.Play(chunk, size, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
mpd_jack_pause(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
JackOutput *jd = (JackOutput *)ao;
|
|
||||||
|
|
||||||
if (jd->shutdown)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
jd->pause = true;
|
pause = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef AudioOutputWrapper<JackOutput> Wrapper;
|
||||||
|
|
||||||
const struct AudioOutputPlugin jack_output_plugin = {
|
const struct AudioOutputPlugin jack_output_plugin = {
|
||||||
"jack",
|
"jack",
|
||||||
mpd_jack_test_default_device,
|
mpd_jack_test_default_device,
|
||||||
mpd_jack_init,
|
mpd_jack_init,
|
||||||
mpd_jack_finish,
|
&Wrapper::Finish,
|
||||||
mpd_jack_enable,
|
&Wrapper::Enable,
|
||||||
mpd_jack_disable,
|
&Wrapper::Disable,
|
||||||
mpd_jack_open,
|
&Wrapper::Open,
|
||||||
mpd_jack_close,
|
&Wrapper::Close,
|
||||||
mpd_jack_delay,
|
&Wrapper::Delay,
|
||||||
nullptr,
|
nullptr,
|
||||||
mpd_jack_play,
|
&Wrapper::Play,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
mpd_jack_pause,
|
&Wrapper::Pause,
|
||||||
nullptr,
|
nullptr,
|
||||||
};
|
};
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "PipeOutputPlugin.hxx"
|
#include "PipeOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Wrapper.hxx"
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@ -29,6 +30,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
class PipeOutput {
|
class PipeOutput {
|
||||||
|
friend AudioOutputWrapper<PipeOutput>;
|
||||||
|
|
||||||
AudioOutput base;
|
AudioOutput base;
|
||||||
|
|
||||||
std::string cmd;
|
std::string cmd;
|
||||||
@ -40,7 +43,7 @@ class PipeOutput {
|
|||||||
bool Configure(const config_param ¶m, Error &error);
|
bool Configure(const config_param ¶m, Error &error);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static AudioOutput *Create(const config_param ¶m, Error &error);
|
static PipeOutput *Create(const config_param ¶m, Error &error);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
bool Open(AudioFormat &audio_format, Error &error);
|
||||||
|
|
||||||
@ -70,7 +73,7 @@ PipeOutput::Configure(const config_param ¶m, Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AudioOutput *
|
inline PipeOutput *
|
||||||
PipeOutput::Create(const config_param ¶m, Error &error)
|
PipeOutput::Create(const config_param ¶m, Error &error)
|
||||||
{
|
{
|
||||||
PipeOutput *po = new PipeOutput();
|
PipeOutput *po = new PipeOutput();
|
||||||
@ -80,21 +83,7 @@ PipeOutput::Create(const config_param ¶m, Error &error)
|
|||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
return &po->base;
|
return po;
|
||||||
}
|
|
||||||
|
|
||||||
static AudioOutput *
|
|
||||||
pipe_output_init(const config_param ¶m, Error &error)
|
|
||||||
{
|
|
||||||
return PipeOutput::Create(param, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pipe_output_finish(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
PipeOutput *pd = (PipeOutput *)ao;
|
|
||||||
|
|
||||||
delete pd;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline bool
|
||||||
@ -110,22 +99,6 @@ PipeOutput::Open(gcc_unused AudioFormat &audio_format, Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
pipe_output_open(AudioOutput *ao, AudioFormat &audio_format, Error &error)
|
|
||||||
{
|
|
||||||
PipeOutput &po = *(PipeOutput *)ao;
|
|
||||||
|
|
||||||
return po.Open(audio_format, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
pipe_output_close(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
PipeOutput &po = *(PipeOutput *)ao;
|
|
||||||
|
|
||||||
po.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
PipeOutput::Play(const void *chunk, size_t size, Error &error)
|
PipeOutput::Play(const void *chunk, size_t size, Error &error)
|
||||||
{
|
{
|
||||||
@ -136,27 +109,20 @@ PipeOutput::Play(const void *chunk, size_t size, Error &error)
|
|||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
typedef AudioOutputWrapper<PipeOutput> Wrapper;
|
||||||
pipe_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
|
||||||
Error &error)
|
|
||||||
{
|
|
||||||
PipeOutput &po = *(PipeOutput *)ao;
|
|
||||||
|
|
||||||
return po.Play(chunk, size, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct AudioOutputPlugin pipe_output_plugin = {
|
const struct AudioOutputPlugin pipe_output_plugin = {
|
||||||
"pipe",
|
"pipe",
|
||||||
nullptr,
|
nullptr,
|
||||||
pipe_output_init,
|
&Wrapper::Init,
|
||||||
pipe_output_finish,
|
&Wrapper::Finish,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
pipe_output_open,
|
&Wrapper::Open,
|
||||||
pipe_output_close,
|
&Wrapper::Close,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
pipe_output_play,
|
&Wrapper::Play,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "RecorderOutputPlugin.hxx"
|
#include "RecorderOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Wrapper.hxx"
|
||||||
#include "encoder/EncoderPlugin.hxx"
|
#include "encoder/EncoderPlugin.hxx"
|
||||||
#include "encoder/EncoderList.hxx"
|
#include "encoder/EncoderList.hxx"
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
@ -213,16 +214,6 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
recorder_output_open(AudioOutput *ao,
|
|
||||||
AudioFormat &audio_format,
|
|
||||||
Error &error)
|
|
||||||
{
|
|
||||||
RecorderOutput &recorder = *(RecorderOutput *)ao;
|
|
||||||
|
|
||||||
return recorder.Open(audio_format, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RecorderOutput::Close()
|
RecorderOutput::Close()
|
||||||
{
|
{
|
||||||
@ -238,14 +229,6 @@ RecorderOutput::Close()
|
|||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
recorder_output_close(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
RecorderOutput &recorder = *(RecorderOutput *)ao;
|
|
||||||
|
|
||||||
recorder.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RecorderOutput::SendTag(const Tag &tag)
|
RecorderOutput::SendTag(const Tag &tag)
|
||||||
{
|
{
|
||||||
@ -275,6 +258,8 @@ recorder_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
|||||||
? size : 0;
|
? size : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef AudioOutputWrapper<RecorderOutput> Wrapper;
|
||||||
|
|
||||||
const struct AudioOutputPlugin recorder_output_plugin = {
|
const struct AudioOutputPlugin recorder_output_plugin = {
|
||||||
"recorder",
|
"recorder",
|
||||||
nullptr,
|
nullptr,
|
||||||
@ -282,8 +267,8 @@ const struct AudioOutputPlugin recorder_output_plugin = {
|
|||||||
recorder_output_finish,
|
recorder_output_finish,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
recorder_output_open,
|
&Wrapper::Open,
|
||||||
recorder_output_close,
|
&Wrapper::Close,
|
||||||
nullptr,
|
nullptr,
|
||||||
recorder_output_send_tag,
|
recorder_output_send_tag,
|
||||||
recorder_output_play,
|
recorder_output_play,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "RoarOutputPlugin.hxx"
|
#include "RoarOutputPlugin.hxx"
|
||||||
#include "../OutputAPI.hxx"
|
#include "../OutputAPI.hxx"
|
||||||
|
#include "../Wrapper.hxx"
|
||||||
#include "mixer/MixerList.hxx"
|
#include "mixer/MixerList.hxx"
|
||||||
#include "thread/Mutex.hxx"
|
#include "thread/Mutex.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
@ -36,6 +37,8 @@
|
|||||||
#undef new
|
#undef new
|
||||||
|
|
||||||
class RoarOutput {
|
class RoarOutput {
|
||||||
|
friend struct AudioOutputWrapper<RoarOutput>;
|
||||||
|
|
||||||
AudioOutput base;
|
AudioOutput base;
|
||||||
|
|
||||||
std::string host, name;
|
std::string host, name;
|
||||||
@ -146,14 +149,6 @@ roar_init(const config_param ¶m, Error &error)
|
|||||||
return *self;
|
return *self;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
roar_finish(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
RoarOutput *self = (RoarOutput *)ao;
|
|
||||||
|
|
||||||
delete self;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
roar_use_audio_format(struct roar_audio_info *info,
|
roar_use_audio_format(struct roar_audio_info *info,
|
||||||
AudioFormat &audio_format)
|
AudioFormat &audio_format)
|
||||||
@ -221,14 +216,6 @@ RoarOutput::Open(AudioFormat &audio_format, Error &error)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
|
||||||
roar_open(AudioOutput *ao, AudioFormat &audio_format, Error &error)
|
|
||||||
{
|
|
||||||
RoarOutput *self = (RoarOutput *)ao;
|
|
||||||
|
|
||||||
return self->Open(audio_format, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RoarOutput::Close()
|
RoarOutput::Close()
|
||||||
{
|
{
|
||||||
@ -242,13 +229,6 @@ RoarOutput::Close()
|
|||||||
roar_disconnect(&con);
|
roar_disconnect(&con);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
roar_close(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
RoarOutput *self = (RoarOutput *)ao;
|
|
||||||
self->Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
RoarOutput::Cancel()
|
RoarOutput::Cancel()
|
||||||
{
|
{
|
||||||
@ -277,14 +257,6 @@ RoarOutput::Cancel()
|
|||||||
alive = true;
|
alive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
roar_cancel(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
RoarOutput *self = (RoarOutput *)ao;
|
|
||||||
|
|
||||||
self->Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
RoarOutput::Play(const void *chunk, size_t size, Error &error)
|
RoarOutput::Play(const void *chunk, size_t size, Error &error)
|
||||||
{
|
{
|
||||||
@ -302,14 +274,6 @@ RoarOutput::Play(const void *chunk, size_t size, Error &error)
|
|||||||
return nbytes;
|
return nbytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
|
||||||
roar_play(AudioOutput *ao, const void *chunk, size_t size,
|
|
||||||
Error &error)
|
|
||||||
{
|
|
||||||
RoarOutput *self = (RoarOutput *)ao;
|
|
||||||
return self->Play(chunk, size, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
roar_tag_convert(TagType type, bool *is_uuid)
|
roar_tag_convert(TagType type, bool *is_uuid)
|
||||||
{
|
{
|
||||||
@ -413,20 +377,22 @@ roar_send_tag(AudioOutput *ao, const Tag &meta)
|
|||||||
self->SendTag(meta);
|
self->SendTag(meta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef AudioOutputWrapper<RoarOutput> Wrapper;
|
||||||
|
|
||||||
const struct AudioOutputPlugin roar_output_plugin = {
|
const struct AudioOutputPlugin roar_output_plugin = {
|
||||||
"roar",
|
"roar",
|
||||||
nullptr,
|
nullptr,
|
||||||
roar_init,
|
roar_init,
|
||||||
roar_finish,
|
&Wrapper::Finish,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
roar_open,
|
&Wrapper::Open,
|
||||||
roar_close,
|
&Wrapper::Close,
|
||||||
nullptr,
|
nullptr,
|
||||||
roar_send_tag,
|
roar_send_tag,
|
||||||
roar_play,
|
&Wrapper::Play,
|
||||||
nullptr,
|
nullptr,
|
||||||
roar_cancel,
|
&Wrapper::Cancel,
|
||||||
nullptr,
|
nullptr,
|
||||||
&roar_mixer_plugin,
|
&roar_mixer_plugin,
|
||||||
};
|
};
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "Play.hxx"
|
#include "Play.hxx"
|
||||||
#include "AndroidSimpleBufferQueue.hxx"
|
#include "AndroidSimpleBufferQueue.hxx"
|
||||||
#include "../../OutputAPI.hxx"
|
#include "../../OutputAPI.hxx"
|
||||||
|
#include "../../Wrapper.hxx"
|
||||||
#include "util/Macros.hxx"
|
#include "util/Macros.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
@ -34,6 +35,8 @@
|
|||||||
#include <SLES/OpenSLES_Android.h>
|
#include <SLES/OpenSLES_Android.h>
|
||||||
|
|
||||||
class SlesOutput {
|
class SlesOutput {
|
||||||
|
friend AudioOutputWrapper<SlesOutput>;
|
||||||
|
|
||||||
static constexpr unsigned N_BUFFERS = 3;
|
static constexpr unsigned N_BUFFERS = 3;
|
||||||
static constexpr size_t BUFFER_SIZE = 65536;
|
static constexpr size_t BUFFER_SIZE = 65536;
|
||||||
|
|
||||||
@ -455,85 +458,22 @@ sles_output_init(const config_param ¶m, Error &error)
|
|||||||
return *sles;
|
return *sles;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
typedef AudioOutputWrapper<SlesOutput> Wrapper;
|
||||||
sles_output_finish(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput *sles = (SlesOutput *)ao;
|
|
||||||
|
|
||||||
delete sles;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
sles_output_open(AudioOutput *ao, AudioFormat &audio_format, Error &error)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
return sles.Open(audio_format, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sles_output_close(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
sles.Close();
|
|
||||||
}
|
|
||||||
|
|
||||||
static unsigned
|
|
||||||
sles_output_delay(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
return sles.Delay();
|
|
||||||
}
|
|
||||||
|
|
||||||
static size_t
|
|
||||||
sles_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
|
||||||
Error &error)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
return sles.Play(chunk, size, error);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sles_output_drain(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
sles.Drain();
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
sles_output_cancel(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
sles.Cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool
|
|
||||||
sles_output_pause(AudioOutput *ao)
|
|
||||||
{
|
|
||||||
SlesOutput &sles = *(SlesOutput *)ao;
|
|
||||||
|
|
||||||
return sles.Pause();
|
|
||||||
}
|
|
||||||
|
|
||||||
const struct AudioOutputPlugin sles_output_plugin = {
|
const struct AudioOutputPlugin sles_output_plugin = {
|
||||||
"sles",
|
"sles",
|
||||||
sles_test_default_device,
|
sles_test_default_device,
|
||||||
sles_output_init,
|
sles_output_init,
|
||||||
sles_output_finish,
|
&Wrapper::Finish,
|
||||||
nullptr,
|
nullptr,
|
||||||
nullptr,
|
nullptr,
|
||||||
sles_output_open,
|
&Wrapper::Open,
|
||||||
sles_output_close,
|
&Wrapper::Close,
|
||||||
sles_output_delay,
|
&Wrapper::Delay,
|
||||||
nullptr,
|
nullptr,
|
||||||
sles_output_play,
|
&Wrapper::Play,
|
||||||
sles_output_drain,
|
&Wrapper::Drain,
|
||||||
sles_output_cancel,
|
&Wrapper::Cancel,
|
||||||
sles_output_pause,
|
&Wrapper::Pause,
|
||||||
nullptr,
|
nullptr,
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user