output/Plugin: remove 'Error&' parameters, use C++ exceptions only
This commit is contained in:
parent
445e82be75
commit
d9cb85df83
|
@ -36,7 +36,7 @@
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
@ -62,7 +62,7 @@ AudioOutput::AudioOutput(const AudioOutputPlugin &_plugin,
|
||||||
}
|
}
|
||||||
|
|
||||||
static const AudioOutputPlugin *
|
static const AudioOutputPlugin *
|
||||||
audio_output_detect(Error &error)
|
audio_output_detect()
|
||||||
{
|
{
|
||||||
LogDefault(output_domain, "Attempt to detect audio output device");
|
LogDefault(output_domain, "Attempt to detect audio output device");
|
||||||
|
|
||||||
|
@ -77,8 +77,7 @@ audio_output_detect(Error &error)
|
||||||
return plugin;
|
return plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
error.Set(output_domain, "Unable to detect an audio device");
|
throw std::runtime_error("Unable to detect an audio device");
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -272,8 +271,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
|
||||||
AudioOutput *
|
AudioOutput *
|
||||||
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
||||||
MixerListener &mixer_listener,
|
MixerListener &mixer_listener,
|
||||||
PlayerControl &pc,
|
PlayerControl &pc)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
const AudioOutputPlugin *plugin;
|
const AudioOutputPlugin *plugin;
|
||||||
|
|
||||||
|
@ -281,34 +279,25 @@ audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
||||||
const char *p;
|
const char *p;
|
||||||
|
|
||||||
p = block.GetBlockValue(AUDIO_OUTPUT_TYPE);
|
p = block.GetBlockValue(AUDIO_OUTPUT_TYPE);
|
||||||
if (p == nullptr) {
|
if (p == nullptr)
|
||||||
error.Set(config_domain,
|
throw std::runtime_error("Missing \"type\" configuration");
|
||||||
"Missing \"type\" configuration");
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
plugin = AudioOutputPlugin_get(p);
|
plugin = AudioOutputPlugin_get(p);
|
||||||
if (plugin == nullptr) {
|
if (plugin == nullptr)
|
||||||
error.Format(config_domain,
|
throw FormatRuntimeError("No such audio output plugin: %s", p);
|
||||||
"No such audio output plugin: %s", p);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
LogWarning(output_domain,
|
LogWarning(output_domain,
|
||||||
"No 'AudioOutput' defined in config file");
|
"No 'AudioOutput' defined in config file");
|
||||||
|
|
||||||
plugin = audio_output_detect(error);
|
plugin = audio_output_detect();
|
||||||
if (plugin == nullptr)
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
FormatDefault(output_domain,
|
FormatDefault(output_domain,
|
||||||
"Successfully detected a %s audio device",
|
"Successfully detected a %s audio device",
|
||||||
plugin->name);
|
plugin->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
AudioOutput *ao = ao_plugin_init(plugin, block, error);
|
AudioOutput *ao = ao_plugin_init(plugin, block);
|
||||||
if (ao == nullptr)
|
assert(ao != nullptr);
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
audio_output_setup(event_loop, *ao, mixer_listener, block);
|
audio_output_setup(event_loop, *ao, mixer_listener, block);
|
||||||
|
|
|
@ -30,7 +30,6 @@
|
||||||
#include "thread/Thread.hxx"
|
#include "thread/Thread.hxx"
|
||||||
#include "system/PeriodClock.hxx"
|
#include "system/PeriodClock.hxx"
|
||||||
|
|
||||||
class Error;
|
|
||||||
class PreparedFilter;
|
class PreparedFilter;
|
||||||
class Filter;
|
class Filter;
|
||||||
class MusicPipe;
|
class MusicPipe;
|
||||||
|
@ -467,8 +466,7 @@ extern struct notify audio_output_client_notify;
|
||||||
AudioOutput *
|
AudioOutput *
|
||||||
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
||||||
MixerListener &mixer_listener,
|
MixerListener &mixer_listener,
|
||||||
PlayerControl &pc,
|
PlayerControl &pc);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
audio_output_free(AudioOutput *ao);
|
audio_output_free(AudioOutput *ao);
|
||||||
|
|
|
@ -26,7 +26,6 @@
|
||||||
#include "MusicPipe.hxx"
|
#include "MusicPipe.hxx"
|
||||||
#include "MusicChunk.hxx"
|
#include "MusicChunk.hxx"
|
||||||
#include "system/FatalError.hxx"
|
#include "system/FatalError.hxx"
|
||||||
#include "util/Error.hxx"
|
|
||||||
#include "config/Block.hxx"
|
#include "config/Block.hxx"
|
||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/ConfigOption.hxx"
|
#include "config/ConfigOption.hxx"
|
||||||
|
@ -54,14 +53,9 @@ static AudioOutput *
|
||||||
LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
|
LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
|
||||||
PlayerControl &pc, const ConfigBlock &block)
|
PlayerControl &pc, const ConfigBlock &block)
|
||||||
try {
|
try {
|
||||||
Error error;
|
return audio_output_new(event_loop, block,
|
||||||
AudioOutput *output = audio_output_new(event_loop, block,
|
mixer_listener,
|
||||||
mixer_listener,
|
pc);
|
||||||
pc, error);
|
|
||||||
if (output == nullptr)
|
|
||||||
throw std::runtime_error(error.GetMessage());
|
|
||||||
|
|
||||||
return output;
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
if (block.line > 0)
|
if (block.line > 0)
|
||||||
FormatFatalError("line %i: %s",
|
FormatFatalError("line %i: %s",
|
||||||
|
|
|
@ -42,7 +42,6 @@ class MixerListener;
|
||||||
struct MusicChunk;
|
struct MusicChunk;
|
||||||
struct PlayerControl;
|
struct PlayerControl;
|
||||||
struct AudioOutput;
|
struct AudioOutput;
|
||||||
class Error;
|
|
||||||
|
|
||||||
class MultipleOutputs {
|
class MultipleOutputs {
|
||||||
MixerListener &mixer_listener;
|
MixerListener &mixer_listener;
|
||||||
|
|
|
@ -24,7 +24,6 @@
|
||||||
#include "mixer/MixerControl.hxx"
|
#include "mixer/MixerControl.hxx"
|
||||||
#include "notify.hxx"
|
#include "notify.hxx"
|
||||||
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
|
#include "filter/plugins/ReplayGainFilterPlugin.hxx"
|
||||||
#include "util/Error.hxx"
|
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
|
|
@ -23,13 +23,12 @@
|
||||||
|
|
||||||
AudioOutput *
|
AudioOutput *
|
||||||
ao_plugin_init(const AudioOutputPlugin *plugin,
|
ao_plugin_init(const AudioOutputPlugin *plugin,
|
||||||
const ConfigBlock &block,
|
const ConfigBlock &block)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
assert(plugin != nullptr);
|
assert(plugin != nullptr);
|
||||||
assert(plugin->init != nullptr);
|
assert(plugin->init != nullptr);
|
||||||
|
|
||||||
return plugin->init(block, error);
|
return plugin->init(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -38,12 +37,11 @@ ao_plugin_finish(AudioOutput *ao)
|
||||||
ao->plugin.finish(ao);
|
ao->plugin.finish(ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
ao_plugin_enable(AudioOutput *ao, Error &error_r)
|
ao_plugin_enable(AudioOutput *ao)
|
||||||
{
|
{
|
||||||
return ao->plugin.enable != nullptr
|
if (ao->plugin.enable != nullptr)
|
||||||
? ao->plugin.enable(ao, error_r)
|
ao->plugin.enable(ao);
|
||||||
: true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -53,11 +51,10 @@ ao_plugin_disable(AudioOutput *ao)
|
||||||
ao->plugin.disable(ao);
|
ao->plugin.disable(ao);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format,
|
ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
return ao->plugin.open(ao, audio_format, error);
|
ao->plugin.open(ao, audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -82,10 +79,9 @@ ao_plugin_send_tag(AudioOutput *ao, const Tag &tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size,
|
ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
return ao->plugin.play(ao, chunk, size, error);
|
return ao->plugin.play(ao, chunk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
|
@ -29,7 +29,6 @@ struct AudioFormat;
|
||||||
struct Tag;
|
struct Tag;
|
||||||
struct AudioOutput;
|
struct AudioOutput;
|
||||||
struct MixerPlugin;
|
struct MixerPlugin;
|
||||||
class Error;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A plugin which controls an audio output device.
|
* A plugin which controls an audio output device.
|
||||||
|
@ -54,10 +53,8 @@ struct AudioOutputPlugin {
|
||||||
*
|
*
|
||||||
* @param param the configuration section, or nullptr if there is
|
* @param param the configuration section, or nullptr if there is
|
||||||
* no configuration
|
* no configuration
|
||||||
* @return nullptr on error, or an opaque pointer to the plugin's
|
|
||||||
* data
|
|
||||||
*/
|
*/
|
||||||
AudioOutput *(*init)(const ConfigBlock &block, Error &error);
|
AudioOutput *(*init)(const ConfigBlock &block);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Free resources allocated by this device.
|
* Free resources allocated by this device.
|
||||||
|
@ -69,10 +66,8 @@ struct AudioOutputPlugin {
|
||||||
* for the device to be opened.
|
* for the device to be opened.
|
||||||
*
|
*
|
||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*
|
|
||||||
* @return true on success, false on error
|
|
||||||
*/
|
*/
|
||||||
bool (*enable)(AudioOutput *data, Error &error);
|
void (*enable)(AudioOutput *data);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Disables the device. It is closed before this method is
|
* Disables the device. It is closed before this method is
|
||||||
|
@ -88,8 +83,7 @@ struct AudioOutputPlugin {
|
||||||
* @param audio_format the audio format in which data is going
|
* @param audio_format the audio format in which data is going
|
||||||
* to be delivered; may be modified by the plugin
|
* to be delivered; may be modified by the plugin
|
||||||
*/
|
*/
|
||||||
bool (*open)(AudioOutput *data, AudioFormat &audio_format,
|
void (*open)(AudioOutput *data, AudioFormat &audio_format);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close the device.
|
* Close the device.
|
||||||
|
@ -118,11 +112,10 @@ struct AudioOutputPlugin {
|
||||||
*
|
*
|
||||||
* Throws #std::runtime_error on error.
|
* Throws #std::runtime_error on error.
|
||||||
*
|
*
|
||||||
* @return the number of bytes played, or 0 on error
|
* @return the number of bytes played
|
||||||
*/
|
*/
|
||||||
size_t (*play)(AudioOutput *data,
|
size_t (*play)(AudioOutput *data,
|
||||||
const void *chunk, size_t size,
|
const void *chunk, size_t size);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Wait until the device has finished playing.
|
* Wait until the device has finished playing.
|
||||||
|
@ -168,21 +161,19 @@ ao_plugin_test_default_device(const AudioOutputPlugin *plugin)
|
||||||
gcc_malloc
|
gcc_malloc
|
||||||
AudioOutput *
|
AudioOutput *
|
||||||
ao_plugin_init(const AudioOutputPlugin *plugin,
|
ao_plugin_init(const AudioOutputPlugin *plugin,
|
||||||
const ConfigBlock &block,
|
const ConfigBlock &block);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ao_plugin_finish(AudioOutput *ao);
|
ao_plugin_finish(AudioOutput *ao);
|
||||||
|
|
||||||
bool
|
void
|
||||||
ao_plugin_enable(AudioOutput *ao, Error &error);
|
ao_plugin_enable(AudioOutput *ao);
|
||||||
|
|
||||||
void
|
void
|
||||||
ao_plugin_disable(AudioOutput *ao);
|
ao_plugin_disable(AudioOutput *ao);
|
||||||
|
|
||||||
bool
|
void
|
||||||
ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format,
|
ao_plugin_open(AudioOutput *ao, AudioFormat &audio_format);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ao_plugin_close(AudioOutput *ao);
|
ao_plugin_close(AudioOutput *ao);
|
||||||
|
@ -195,8 +186,7 @@ void
|
||||||
ao_plugin_send_tag(AudioOutput *ao, const Tag &tag);
|
ao_plugin_send_tag(AudioOutput *ao, const Tag &tag);
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size,
|
ao_plugin_play(AudioOutput *ao, const void *chunk, size_t size);
|
||||||
Error &error);
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ao_plugin_drain(AudioOutput *ao);
|
ao_plugin_drain(AudioOutput *ao);
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "thread/Util.hxx"
|
#include "thread/Util.hxx"
|
||||||
#include "thread/Slack.hxx"
|
#include "thread/Slack.hxx"
|
||||||
#include "thread/Name.hxx"
|
#include "thread/Name.hxx"
|
||||||
#include "util/Error.hxx"
|
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
@ -62,13 +61,7 @@ AudioOutput::Enable()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
Error error;
|
ao_plugin_enable(this);
|
||||||
if (!ao_plugin_enable(this, error)) {
|
|
||||||
FormatError(error,
|
|
||||||
"Failed to enable \"%s\" [%s]",
|
|
||||||
name, plugin.name);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e,
|
FormatError(e,
|
||||||
"Failed to enable \"%s\" [%s]",
|
"Failed to enable \"%s\" [%s]",
|
||||||
|
@ -138,8 +131,6 @@ AudioOutput::CloseFilter()
|
||||||
inline void
|
inline void
|
||||||
AudioOutput::Open()
|
AudioOutput::Open()
|
||||||
{
|
{
|
||||||
bool success;
|
|
||||||
Error error;
|
|
||||||
struct audio_format_string af_string;
|
struct audio_format_string af_string;
|
||||||
|
|
||||||
assert(!open);
|
assert(!open);
|
||||||
|
@ -179,7 +170,7 @@ AudioOutput::Open()
|
||||||
|
|
||||||
retry_without_dsd:
|
retry_without_dsd:
|
||||||
try {
|
try {
|
||||||
success = ao_plugin_open(this, out_audio_format, error);
|
ao_plugin_open(this, out_audio_format);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "Failed to open \"%s\" [%s]",
|
FormatError(e, "Failed to open \"%s\" [%s]",
|
||||||
name, plugin.name);
|
name, plugin.name);
|
||||||
|
@ -194,19 +185,6 @@ AudioOutput::Open()
|
||||||
|
|
||||||
assert(!open);
|
assert(!open);
|
||||||
|
|
||||||
if (!success) {
|
|
||||||
FormatError(error, "Failed to open \"%s\" [%s]",
|
|
||||||
name, plugin.name);
|
|
||||||
|
|
||||||
{
|
|
||||||
const ScopeUnlock unlock(mutex);
|
|
||||||
CloseFilter();
|
|
||||||
}
|
|
||||||
|
|
||||||
fail_timer.Update();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
convert_filter_set(convert_filter.Get(), out_audio_format);
|
convert_filter_set(convert_filter.Get(), out_audio_format);
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
|
@ -289,8 +267,6 @@ AudioOutput::CloseOutput(bool drain)
|
||||||
void
|
void
|
||||||
AudioOutput::ReopenFilter()
|
AudioOutput::ReopenFilter()
|
||||||
{
|
{
|
||||||
Error error;
|
|
||||||
|
|
||||||
{
|
{
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
CloseFilter();
|
CloseFilter();
|
||||||
|
@ -486,8 +462,6 @@ AudioOutput::PlayChunk(const MusicChunk *chunk)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Error error;
|
|
||||||
|
|
||||||
while (!data.IsEmpty() && command == Command::NONE) {
|
while (!data.IsEmpty() && command == Command::NONE) {
|
||||||
if (!WaitForDelay())
|
if (!WaitForDelay())
|
||||||
break;
|
break;
|
||||||
|
@ -496,13 +470,7 @@ AudioOutput::PlayChunk(const MusicChunk *chunk)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const ScopeUnlock unlock(mutex);
|
const ScopeUnlock unlock(mutex);
|
||||||
nbytes = ao_plugin_play(this, data.data, data.size,
|
nbytes = ao_plugin_play(this, data.data, data.size);
|
||||||
error);
|
|
||||||
|
|
||||||
if (nbytes == 0)
|
|
||||||
/* play()==0 means failure */
|
|
||||||
FormatError(error, "\"%s\" [%s] failed to play",
|
|
||||||
name, plugin.name);
|
|
||||||
} catch (const std::runtime_error &e) {
|
} catch (const std::runtime_error &e) {
|
||||||
FormatError(e, "\"%s\" [%s] failed to play",
|
FormatError(e, "\"%s\" [%s] failed to play",
|
||||||
name, plugin.name);
|
name, plugin.name);
|
||||||
|
|
|
@ -30,11 +30,9 @@ struct AudioOutputWrapper {
|
||||||
return ContainerCast(ao, &T::base);
|
return ContainerCast(ao, &T::base);
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *Init(const ConfigBlock &block, Error &error) {
|
static AudioOutput *Init(const ConfigBlock &block) {
|
||||||
T *t = T::Create(block, error);
|
T *t = T::Create(block);
|
||||||
return t != nullptr
|
return &t->base;
|
||||||
? &t->base
|
|
||||||
: nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Finish(AudioOutput *ao) {
|
static void Finish(AudioOutput *ao) {
|
||||||
|
@ -42,9 +40,9 @@ struct AudioOutputWrapper {
|
||||||
delete t;
|
delete t;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Enable(AudioOutput *ao, Error &error) {
|
static void Enable(AudioOutput *ao) {
|
||||||
T &t = Cast(*ao);
|
T &t = Cast(*ao);
|
||||||
return t.Enable(error);
|
t.Enable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Disable(AudioOutput *ao) {
|
static void Disable(AudioOutput *ao) {
|
||||||
|
@ -52,10 +50,9 @@ struct AudioOutputWrapper {
|
||||||
t.Disable();
|
t.Disable();
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool Open(AudioOutput *ao, AudioFormat &audio_format,
|
static void Open(AudioOutput *ao, AudioFormat &audio_format) {
|
||||||
Error &error) {
|
|
||||||
T &t = Cast(*ao);
|
T &t = Cast(*ao);
|
||||||
return t.Open(audio_format, error);
|
t.Open(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Close(AudioOutput *ao) {
|
static void Close(AudioOutput *ao) {
|
||||||
|
@ -75,10 +72,9 @@ struct AudioOutputWrapper {
|
||||||
t.SendTag(tag);
|
t.SendTag(tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t Play(AudioOutput *ao, const void *chunk, size_t size,
|
static size_t Play(AudioOutput *ao, const void *chunk, size_t size) {
|
||||||
Error &error) {
|
|
||||||
T &t = Cast(*ao);
|
T &t = Cast(*ao);
|
||||||
return t.Play(chunk, size, error);
|
return t.Play(chunk, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Drain(AudioOutput *ao) {
|
static void Drain(AudioOutput *ao) {
|
||||||
|
|
|
@ -133,15 +133,15 @@ struct AlsaOutput {
|
||||||
return device.empty() ? default_device : device.c_str();
|
return device.empty() ? default_device : device.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
static AlsaOutput *Create(const ConfigBlock &block, Error &error);
|
static AlsaOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Enable(Error &error);
|
void Enable();
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Drain();
|
void Drain();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
|
@ -195,16 +195,15 @@ AlsaOutput::AlsaOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline AlsaOutput *
|
inline AlsaOutput *
|
||||||
AlsaOutput::Create(const ConfigBlock &block, Error &)
|
AlsaOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new AlsaOutput(block);
|
return new AlsaOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
AlsaOutput::Enable(gcc_unused Error &error)
|
AlsaOutput::Enable()
|
||||||
{
|
{
|
||||||
pcm_export.Construct();
|
pcm_export.Construct();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -719,8 +718,8 @@ AlsaOutput::SetupOrDop(AudioFormat &audio_format, PcmExport::Params ¶ms)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
AlsaOutput::Open(AudioFormat &audio_format, gcc_unused Error &error)
|
AlsaOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
int err = snd_pcm_open(&pcm, GetDevice(),
|
int err = snd_pcm_open(&pcm, GetDevice(),
|
||||||
SND_PCM_STREAM_PLAYBACK, mode);
|
SND_PCM_STREAM_PLAYBACK, mode);
|
||||||
|
@ -751,8 +750,6 @@ AlsaOutput::Open(AudioFormat &audio_format, gcc_unused Error &error)
|
||||||
out_frame_size = pcm_export->GetFrameSize(audio_format);
|
out_frame_size = pcm_export->GetFrameSize(audio_format);
|
||||||
|
|
||||||
must_prepare = false;
|
must_prepare = false;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline int
|
inline int
|
||||||
|
@ -832,7 +829,7 @@ AlsaOutput::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
AlsaOutput::Play(const void *chunk, size_t size, gcc_unused Error &error)
|
AlsaOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
assert(size > 0);
|
assert(size > 0);
|
||||||
assert(size % in_frame_size == 0);
|
assert(size % in_frame_size == 0);
|
||||||
|
|
|
@ -121,7 +121,7 @@ AoOutput::AoOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
ao_output_init(const ConfigBlock &block, gcc_unused Error &error)
|
ao_output_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return &(new AoOutput(block))->base;
|
return &(new AoOutput(block))->base;
|
||||||
}
|
}
|
||||||
|
@ -148,9 +148,8 @@ ao_output_close(AudioOutput *ao)
|
||||||
ao_close(ad->device);
|
ao_close(ad->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
ao_output_open(AudioOutput *ao, AudioFormat &audio_format,
|
ao_output_open(AudioOutput *ao, AudioFormat &audio_format)
|
||||||
gcc_unused Error &error)
|
|
||||||
{
|
{
|
||||||
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
|
ao_sample_format format = OUR_AO_FORMAT_INITIALIZER;
|
||||||
AoOutput *ad = (AoOutput *)ao;
|
AoOutput *ad = (AoOutput *)ao;
|
||||||
|
@ -181,8 +180,6 @@ ao_output_open(AudioOutput *ao, AudioFormat &audio_format,
|
||||||
|
|
||||||
if (ad->device == nullptr)
|
if (ad->device == nullptr)
|
||||||
throw MakeAoError();
|
throw MakeAoError();
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -203,8 +200,7 @@ static int ao_play_deconst(ao_device *device, const void *output_samples,
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
ao_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
ao_output_play(AudioOutput *ao, const void *chunk, size_t size)
|
||||||
gcc_unused Error &error)
|
|
||||||
{
|
{
|
||||||
AoOutput *ad = (AoOutput *)ao;
|
AoOutput *ad = (AoOutput *)ao;
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ public:
|
||||||
CloseFifo();
|
CloseFifo();
|
||||||
}
|
}
|
||||||
|
|
||||||
static FifoOutput *Create(const ConfigBlock &block, Error &error);
|
static FifoOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
void Create();
|
void Create();
|
||||||
void Check();
|
void Check();
|
||||||
|
@ -63,11 +63,11 @@ public:
|
||||||
void OpenFifo();
|
void OpenFifo();
|
||||||
void CloseFifo();
|
void CloseFifo();
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
unsigned Delay() const;
|
unsigned Delay() const;
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -169,16 +169,15 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
inline FifoOutput *
|
inline FifoOutput *
|
||||||
FifoOutput::Create(const ConfigBlock &block, Error &)
|
FifoOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new FifoOutput(block);
|
return new FifoOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
FifoOutput::Open(AudioFormat &audio_format, gcc_unused Error &error)
|
FifoOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
timer = new Timer(audio_format);
|
timer = new Timer(audio_format);
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -214,7 +213,7 @@ FifoOutput::Delay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
FifoOutput::Play(const void *chunk, size_t size, Error &)
|
FifoOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
if (!timer->IsStarted())
|
if (!timer->IsStarted())
|
||||||
timer->Start();
|
timer->Start();
|
||||||
|
|
|
@ -71,12 +71,12 @@ public:
|
||||||
|
|
||||||
~HaikuOutput();
|
~HaikuOutput();
|
||||||
|
|
||||||
static HaikuOutput *Create(const ConfigBlock &block, Error &error);
|
static HaikuOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
size_t Delay();
|
size_t Delay();
|
||||||
|
@ -119,7 +119,7 @@ haiku_test_default_device(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline HaikuOutput *
|
inline HaikuOutput *
|
||||||
HaikuOutput::Create(const ConfigBlock &block, Error &)
|
HaikuOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
initialize_application();
|
initialize_application();
|
||||||
|
|
||||||
|
@ -184,8 +184,8 @@ HaikuOutput::FillBuffer(void* _buffer, size_t size,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
HaikuOutput::Open(AudioFormat &audio_format, Error &)
|
HaikuOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
status_t err;
|
status_t err;
|
||||||
format = media_multi_audio_format::wildcard;
|
format = media_multi_audio_format::wildcard;
|
||||||
|
@ -261,12 +261,10 @@ HaikuOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
sound_player->SetVolume(1.0);
|
sound_player->SetVolume(1.0);
|
||||||
sound_player->Start();
|
sound_player->Start();
|
||||||
sound_player->SetHasData(false);
|
sound_player->SetHasData(false);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
HaikuOutput::Play(const void *chunk, size_t size, gcc_unused Error &error)
|
HaikuOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
BSoundPlayer* const soundPlayer = sound_player;
|
BSoundPlayer* const soundPlayer = sound_player;
|
||||||
const uint8 *data = (const uint8 *)chunk;
|
const uint8 *data = (const uint8 *)chunk;
|
||||||
|
|
|
@ -99,10 +99,10 @@ struct JackOutput {
|
||||||
shutdown = true;
|
shutdown = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Enable(Error &error);
|
void Enable();
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
bool Open(AudioFormat &new_audio_format, Error &error);
|
void Open(AudioFormat &new_audio_format);
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
Stop();
|
Stop();
|
||||||
|
@ -134,7 +134,7 @@ struct JackOutput {
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
|
|
||||||
bool Pause();
|
bool Pause();
|
||||||
};
|
};
|
||||||
|
@ -420,14 +420,13 @@ mpd_jack_test_default_device(void)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
JackOutput::Enable(Error &)
|
JackOutput::Enable()
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < num_source_ports; ++i)
|
for (unsigned i = 0; i < num_source_ports; ++i)
|
||||||
ringbuffer[i] = nullptr;
|
ringbuffer[i] = nullptr;
|
||||||
|
|
||||||
Connect();
|
Connect();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -445,7 +444,7 @@ JackOutput::Disable()
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
mpd_jack_init(const ConfigBlock &block, Error &)
|
mpd_jack_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
jack_set_error_function(mpd_jack_error);
|
jack_set_error_function(mpd_jack_error);
|
||||||
|
|
||||||
|
@ -580,8 +579,8 @@ JackOutput::Start()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
JackOutput::Open(AudioFormat &new_audio_format, Error &)
|
JackOutput::Open(AudioFormat &new_audio_format)
|
||||||
{
|
{
|
||||||
pause = false;
|
pause = false;
|
||||||
|
|
||||||
|
@ -595,7 +594,6 @@ JackOutput::Open(AudioFormat &new_audio_format, Error &)
|
||||||
audio_format = new_audio_format;
|
audio_format = new_audio_format;
|
||||||
|
|
||||||
Start();
|
Start();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
|
@ -640,7 +638,7 @@ JackOutput::WriteSamples(const float *src, size_t n_frames)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
JackOutput::Play(const void *chunk, size_t size, Error &)
|
JackOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
pause = false;
|
pause = false;
|
||||||
|
|
||||||
|
|
|
@ -37,13 +37,11 @@ public:
|
||||||
:base(null_output_plugin, block),
|
:base(null_output_plugin, block),
|
||||||
sync(block.GetBlockValue("sync", true)) {}
|
sync(block.GetBlockValue("sync", true)) {}
|
||||||
|
|
||||||
static NullOutput *Create(const ConfigBlock &block, Error &error);
|
static NullOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, gcc_unused Error &error) {
|
void Open(AudioFormat &audio_format) {
|
||||||
if (sync)
|
if (sync)
|
||||||
timer = new Timer(audio_format);
|
timer = new Timer(audio_format);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
|
@ -57,8 +55,7 @@ public:
|
||||||
: 0;
|
: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(gcc_unused const void *chunk, size_t size,
|
size_t Play(gcc_unused const void *chunk, size_t size) {
|
||||||
gcc_unused Error &error) {
|
|
||||||
if (sync) {
|
if (sync) {
|
||||||
if (!timer->IsStarted())
|
if (!timer->IsStarted())
|
||||||
timer->Start();
|
timer->Start();
|
||||||
|
@ -75,7 +72,7 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
inline NullOutput *
|
inline NullOutput *
|
||||||
NullOutput::Create(const ConfigBlock &block, Error &)
|
NullOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new NullOutput(block);
|
return new NullOutput(block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,7 +104,7 @@ OSXOutput::OSXOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
osx_output_init(const ConfigBlock &block, Error &)
|
osx_output_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
OSXOutput *oo = new OSXOutput(block);
|
OSXOutput *oo = new OSXOutput(block);
|
||||||
|
|
||||||
|
@ -512,8 +512,8 @@ osx_render(void *vdata,
|
||||||
return noErr;
|
return noErr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
osx_output_enable(AudioOutput *ao, Error &)
|
osx_output_enable(AudioOutput *ao)
|
||||||
{
|
{
|
||||||
char errormsg[1024];
|
char errormsg[1024];
|
||||||
OSXOutput *oo = (OSXOutput *)ao;
|
OSXOutput *oo = (OSXOutput *)ao;
|
||||||
|
@ -546,8 +546,6 @@ osx_output_enable(AudioOutput *ao, Error &)
|
||||||
if (oo->hog_device) {
|
if (oo->hog_device) {
|
||||||
osx_output_hog_device(oo->dev_id, true);
|
osx_output_hog_device(oo->dev_id, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -573,9 +571,8 @@ osx_output_close(AudioOutput *ao)
|
||||||
delete od->ring_buffer;
|
delete od->ring_buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
osx_output_open(AudioOutput *ao, AudioFormat &audio_format,
|
osx_output_open(AudioOutput *ao, AudioFormat &audio_format)
|
||||||
Error &)
|
|
||||||
{
|
{
|
||||||
char errormsg[1024];
|
char errormsg[1024];
|
||||||
OSXOutput *od = (OSXOutput *)ao;
|
OSXOutput *od = (OSXOutput *)ao;
|
||||||
|
@ -662,13 +659,10 @@ osx_output_open(AudioOutput *ao, AudioFormat &audio_format,
|
||||||
throw FormatRuntimeError("unable to start audio output: %s",
|
throw FormatRuntimeError("unable to start audio output: %s",
|
||||||
errormsg);
|
errormsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
osx_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
osx_output_play(AudioOutput *ao, const void *chunk, size_t size)
|
||||||
gcc_unused Error &error)
|
|
||||||
{
|
{
|
||||||
OSXOutput *od = (OSXOutput *)ao;
|
OSXOutput *od = (OSXOutput *)ao;
|
||||||
return od->ring_buffer->push((uint8_t *)chunk, size);
|
return od->ring_buffer->push((uint8_t *)chunk, size);
|
||||||
|
|
|
@ -52,10 +52,9 @@ class OpenALOutput {
|
||||||
|
|
||||||
OpenALOutput(const ConfigBlock &block);
|
OpenALOutput(const ConfigBlock &block);
|
||||||
|
|
||||||
static OpenALOutput *Create(const ConfigBlock &block, Error &error);
|
static OpenALOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
|
||||||
|
|
||||||
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
|
@ -68,7 +67,7 @@ class OpenALOutput {
|
||||||
: 50;
|
: 50;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
|
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
|
@ -147,13 +146,13 @@ OpenALOutput::OpenALOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline OpenALOutput *
|
inline OpenALOutput *
|
||||||
OpenALOutput::Create(const ConfigBlock &block, Error &)
|
OpenALOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new OpenALOutput(block);
|
return new OpenALOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
OpenALOutput::Open(AudioFormat &audio_format, Error &)
|
OpenALOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
format = openal_audio_format(audio_format);
|
format = openal_audio_format(audio_format);
|
||||||
|
|
||||||
|
@ -174,8 +173,6 @@ OpenALOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
|
|
||||||
filled = 0;
|
filled = 0;
|
||||||
frequency = audio_format.sample_rate;
|
frequency = audio_format.sample_rate;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -189,7 +186,7 @@ OpenALOutput::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
OpenALOutput::Play(const void *chunk, size_t size, gcc_unused Error &error)
|
OpenALOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
if (alcGetCurrentContext() != context)
|
if (alcGetCurrentContext() != context)
|
||||||
alcMakeContextCurrent(context);
|
alcMakeContextCurrent(context);
|
||||||
|
|
|
@ -89,12 +89,11 @@ public:
|
||||||
:base(oss_output_plugin, block),
|
:base(oss_output_plugin, block),
|
||||||
fd(-1), device(_device) {}
|
fd(-1), device(_device) {}
|
||||||
|
|
||||||
static OssOutput *Create(const ConfigBlock &block, Error &error);
|
static OssOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
#ifdef AFMT_S24_PACKED
|
#ifdef AFMT_S24_PACKED
|
||||||
bool Enable(gcc_unused Error &error) {
|
void Enable() {
|
||||||
pcm_export.Construct();
|
pcm_export.Construct();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Disable() {
|
void Disable() {
|
||||||
|
@ -102,13 +101,13 @@ public:
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
DoClose();
|
DoClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -227,7 +226,7 @@ oss_open_default()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline OssOutput *
|
inline OssOutput *
|
||||||
OssOutput::Create(const ConfigBlock &block, gcc_unused Error &error)
|
OssOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
const char *device = block.GetBlockValue("device");
|
const char *device = block.GetBlockValue("device");
|
||||||
if (device != nullptr)
|
if (device != nullptr)
|
||||||
|
@ -638,8 +637,8 @@ try {
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
OssOutput::Open(AudioFormat &_audio_format, Error &)
|
OssOutput::Open(AudioFormat &_audio_format)
|
||||||
try {
|
try {
|
||||||
fd = open_cloexec(device, O_WRONLY, 0);
|
fd = open_cloexec(device, O_WRONLY, 0);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
|
@ -648,7 +647,6 @@ try {
|
||||||
Setup(_audio_format);
|
Setup(_audio_format);
|
||||||
|
|
||||||
audio_format = _audio_format;
|
audio_format = _audio_format;
|
||||||
return true;
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
DoClose();
|
DoClose();
|
||||||
throw;
|
throw;
|
||||||
|
@ -664,7 +662,7 @@ OssOutput::Cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
OssOutput::Play(const void *chunk, size_t size, Error &)
|
OssOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
|
|
||||||
|
|
|
@ -39,15 +39,15 @@ class PipeOutput {
|
||||||
PipeOutput(const ConfigBlock &block);
|
PipeOutput(const ConfigBlock &block);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static PipeOutput *Create(const ConfigBlock &block, Error &error);
|
static PipeOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
|
|
||||||
void Close() {
|
void Close() {
|
||||||
pclose(fh);
|
pclose(fh);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
};
|
};
|
||||||
|
|
||||||
PipeOutput::PipeOutput(const ConfigBlock &block)
|
PipeOutput::PipeOutput(const ConfigBlock &block)
|
||||||
|
@ -59,23 +59,21 @@ PipeOutput::PipeOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline PipeOutput *
|
inline PipeOutput *
|
||||||
PipeOutput::Create(const ConfigBlock &block, Error &)
|
PipeOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new PipeOutput(block);
|
return new PipeOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
PipeOutput::Open(gcc_unused AudioFormat &audio_format, Error &)
|
PipeOutput::Open(gcc_unused AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
fh = popen(cmd.c_str(), "w");
|
fh = popen(cmd.c_str(), "w");
|
||||||
if (fh == nullptr)
|
if (fh == nullptr)
|
||||||
throw FormatErrno("Error opening pipe \"%s\"", cmd.c_str());
|
throw FormatErrno("Error opening pipe \"%s\"", cmd.c_str());
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
PipeOutput::Play(const void *chunk, size_t size, Error &)
|
PipeOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
size_t nbytes = fwrite(chunk, 1, size, fh);
|
size_t nbytes = fwrite(chunk, 1, size, fh);
|
||||||
if (nbytes == 0)
|
if (nbytes == 0)
|
||||||
|
|
|
@ -93,16 +93,16 @@ public:
|
||||||
gcc_const
|
gcc_const
|
||||||
static bool TestDefaultDevice();
|
static bool TestDefaultDevice();
|
||||||
|
|
||||||
static PulseOutput *Create(const ConfigBlock &block, Error &error);
|
static PulseOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Enable(Error &error);
|
void Enable();
|
||||||
void Disable();
|
void Disable();
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
unsigned Delay();
|
unsigned Delay();
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
bool Pause();
|
bool Pause();
|
||||||
|
|
||||||
|
@ -415,13 +415,13 @@ PulseOutput::SetupContext()
|
||||||
}
|
}
|
||||||
|
|
||||||
PulseOutput *
|
PulseOutput *
|
||||||
PulseOutput::Create(const ConfigBlock &block, gcc_unused Error &error)
|
PulseOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new PulseOutput(block);
|
return new PulseOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
PulseOutput::Enable(gcc_unused Error &error)
|
PulseOutput::Enable()
|
||||||
{
|
{
|
||||||
assert(mainloop == nullptr);
|
assert(mainloop == nullptr);
|
||||||
|
|
||||||
|
@ -454,8 +454,6 @@ PulseOutput::Enable(gcc_unused Error &error)
|
||||||
}
|
}
|
||||||
|
|
||||||
pa_threaded_mainloop_unlock(mainloop);
|
pa_threaded_mainloop_unlock(mainloop);
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -607,8 +605,8 @@ PulseOutput::SetupStream(const pa_sample_spec &ss)
|
||||||
pulse_output_stream_write_cb, this);
|
pulse_output_stream_write_cb, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
PulseOutput::Open(AudioFormat &audio_format, gcc_unused Error &error)
|
PulseOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
assert(mainloop != nullptr);
|
assert(mainloop != nullptr);
|
||||||
|
|
||||||
|
@ -676,8 +674,6 @@ PulseOutput::Open(AudioFormat &audio_format, gcc_unused Error &error)
|
||||||
throw MakePulseError(context,
|
throw MakePulseError(context,
|
||||||
"pa_stream_connect_playback() has failed");
|
"pa_stream_connect_playback() has failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -759,7 +755,7 @@ PulseOutput::Delay()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
PulseOutput::Play(const void *chunk, size_t size, gcc_unused Error &error)
|
PulseOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
assert(mainloop != nullptr);
|
assert(mainloop != nullptr);
|
||||||
assert(stream != nullptr);
|
assert(stream != nullptr);
|
||||||
|
|
|
@ -23,7 +23,6 @@
|
||||||
class PulseOutput;
|
class PulseOutput;
|
||||||
class PulseMixer;
|
class PulseMixer;
|
||||||
struct pa_cvolume;
|
struct pa_cvolume;
|
||||||
class Error;
|
|
||||||
|
|
||||||
extern const struct AudioOutputPlugin pulse_output_plugin;
|
extern const struct AudioOutputPlugin pulse_output_plugin;
|
||||||
|
|
||||||
|
|
|
@ -81,9 +81,9 @@ class RecorderOutput {
|
||||||
delete prepared_encoder;
|
delete prepared_encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
static RecorderOutput *Create(const ConfigBlock &block, Error &error);
|
static RecorderOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -93,7 +93,7 @@ class RecorderOutput {
|
||||||
|
|
||||||
void SendTag(const Tag &tag);
|
void SendTag(const Tag &tag);
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
gcc_pure
|
gcc_pure
|
||||||
|
@ -141,7 +141,7 @@ RecorderOutput::RecorderOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
RecorderOutput *
|
RecorderOutput *
|
||||||
RecorderOutput::Create(const ConfigBlock &block, Error &)
|
RecorderOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new RecorderOutput(block);
|
return new RecorderOutput(block);
|
||||||
}
|
}
|
||||||
|
@ -154,8 +154,8 @@ RecorderOutput::EncoderToFile()
|
||||||
EncoderToOutputStream(*file, *encoder);
|
EncoderToOutputStream(*file, *encoder);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
RecorderOutput::Open(AudioFormat &audio_format, Error &)
|
RecorderOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
/* create the output file */
|
/* create the output file */
|
||||||
|
|
||||||
|
@ -195,8 +195,6 @@ RecorderOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
soon as we have received a tag */
|
soon as we have received a tag */
|
||||||
delete encoder;
|
delete encoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -349,7 +347,7 @@ RecorderOutput::SendTag(const Tag &tag)
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
RecorderOutput::Play(const void *chunk, size_t size, Error &)
|
RecorderOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
if (file == nullptr) {
|
if (file == nullptr) {
|
||||||
/* not currently encoding to a file; discard incoming
|
/* not currently encoding to a file; discard incoming
|
||||||
|
|
|
@ -58,11 +58,11 @@ public:
|
||||||
return &base;
|
return &base;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
void SendTag(const Tag &tag);
|
void SendTag(const Tag &tag);
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
int GetVolume() const;
|
int GetVolume() const;
|
||||||
|
@ -134,7 +134,7 @@ roar_output_set_volume(RoarOutput &roar, unsigned volume)
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
roar_init(const ConfigBlock &block, Error &)
|
roar_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return *new RoarOutput(block);
|
return *new RoarOutput(block);
|
||||||
}
|
}
|
||||||
|
@ -174,8 +174,8 @@ roar_use_audio_format(struct roar_audio_info *info,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
RoarOutput::Open(AudioFormat &audio_format, Error &)
|
RoarOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
const ScopeLock protect(mutex);
|
const ScopeLock protect(mutex);
|
||||||
|
|
||||||
|
@ -196,7 +196,6 @@ RoarOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
|
|
||||||
roar_vs_role(vss, role, &err);
|
roar_vs_role(vss, role, &err);
|
||||||
alive = true;
|
alive = true;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -241,7 +240,7 @@ RoarOutput::Cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
RoarOutput::Play(const void *chunk, size_t size, Error &)
|
RoarOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
if (vss == nullptr)
|
if (vss == nullptr)
|
||||||
throw std::runtime_error("Connection is invalid");
|
throw std::runtime_error("Connection is invalid");
|
||||||
|
|
|
@ -58,14 +58,14 @@ struct ShoutOutput final {
|
||||||
explicit ShoutOutput(const ConfigBlock &block);
|
explicit ShoutOutput(const ConfigBlock &block);
|
||||||
~ShoutOutput();
|
~ShoutOutput();
|
||||||
|
|
||||||
static ShoutOutput *Create(const ConfigBlock &block, Error &error);
|
static ShoutOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
unsigned Delay() const;
|
unsigned Delay() const;
|
||||||
void SendTag(const Tag &tag);
|
void SendTag(const Tag &tag);
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
bool Pause();
|
bool Pause();
|
||||||
};
|
};
|
||||||
|
@ -246,7 +246,7 @@ ShoutOutput::~ShoutOutput()
|
||||||
}
|
}
|
||||||
|
|
||||||
ShoutOutput *
|
ShoutOutput *
|
||||||
ShoutOutput::Create(const ConfigBlock &block, Error &)
|
ShoutOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
if (shout_init_count == 0)
|
if (shout_init_count == 0)
|
||||||
shout_init();
|
shout_init();
|
||||||
|
@ -340,8 +340,8 @@ shout_connect(ShoutOutput *sd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
ShoutOutput::Open(AudioFormat &audio_format, Error &)
|
ShoutOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
shout_connect(this);
|
shout_connect(this);
|
||||||
|
|
||||||
|
@ -358,8 +358,6 @@ ShoutOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
shout_close(shout_conn);
|
shout_close(shout_conn);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned
|
unsigned
|
||||||
|
@ -373,7 +371,7 @@ ShoutOutput::Delay() const
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
ShoutOutput::Play(const void *chunk, size_t size, Error &)
|
ShoutOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
encoder->Write(chunk, size);
|
encoder->Write(chunk, size);
|
||||||
write_page(this);
|
write_page(this);
|
||||||
|
|
|
@ -47,14 +47,12 @@ class SndioOutput {
|
||||||
public:
|
public:
|
||||||
SndioOutput(const ConfigBlock &block);
|
SndioOutput(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Configure(const ConfigBlock &block, Error &error);
|
static SndioOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
static SndioOutput *Create(const ConfigBlock &block, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
|
||||||
void Close();
|
void Close();
|
||||||
unsigned Delay() const;
|
unsigned Delay() const;
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Cancel();
|
void Cancel();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -67,7 +65,7 @@ SndioOutput::SndioOutput(const ConfigBlock &block)
|
||||||
}
|
}
|
||||||
|
|
||||||
SndioOutput *
|
SndioOutput *
|
||||||
SndioOutput::Create(const ConfigBlock &block, Error &)
|
SndioOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new SndioOutput(block);
|
return new SndioOutput(block);
|
||||||
}
|
}
|
||||||
|
@ -88,8 +86,8 @@ sndio_test_default_device()
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
SndioOutput::Open(AudioFormat &audio_format, Error &)
|
SndioOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
struct sio_par par;
|
struct sio_par par;
|
||||||
unsigned bits, rate, chans;
|
unsigned bits, rate, chans;
|
||||||
|
@ -145,8 +143,6 @@ SndioOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
sio_close(sio_hdl);
|
sio_close(sio_hdl);
|
||||||
throw std::runtime_error("Failed to start audio device");
|
throw std::runtime_error("Failed to start audio device");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -156,7 +152,7 @@ SndioOutput::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
SndioOutput::Play(const void *chunk, size_t size, Error &)
|
SndioOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
size_t n;
|
size_t n;
|
||||||
|
|
||||||
|
|
|
@ -72,7 +72,7 @@ solaris_output_test_default_device(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
solaris_output_init(const ConfigBlock &block, Error &)
|
solaris_output_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
SolarisOutput *so = new SolarisOutput(block);
|
SolarisOutput *so = new SolarisOutput(block);
|
||||||
return &so->base;
|
return &so->base;
|
||||||
|
@ -86,8 +86,8 @@ solaris_output_finish(AudioOutput *ao)
|
||||||
delete so;
|
delete so;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
solaris_output_open(AudioOutput *ao, AudioFormat &audio_format, Error &)
|
solaris_output_open(AudioOutput *ao, AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
SolarisOutput *so = (SolarisOutput *)ao;
|
SolarisOutput *so = (SolarisOutput *)ao;
|
||||||
struct audio_info info;
|
struct audio_info info;
|
||||||
|
@ -130,8 +130,6 @@ solaris_output_open(AudioOutput *ao, AudioFormat &audio_format, Error &)
|
||||||
close(so->fd);
|
close(so->fd);
|
||||||
throw MakeErrno(e, "AUDIO_SETINFO failed");
|
throw MakeErrno(e, "AUDIO_SETINFO failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -143,8 +141,7 @@ solaris_output_close(AudioOutput *ao)
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
solaris_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
solaris_output_play(AudioOutput *ao, const void *chunk, size_t size)
|
||||||
Error &)
|
|
||||||
{
|
{
|
||||||
SolarisOutput *so = (SolarisOutput *)ao;
|
SolarisOutput *so = (SolarisOutput *)ao;
|
||||||
ssize_t nbytes;
|
ssize_t nbytes;
|
||||||
|
|
|
@ -63,14 +63,14 @@ public:
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WinmmOutput *Create(const ConfigBlock &block, Error &) {
|
static WinmmOutput *Create(const ConfigBlock &block) {
|
||||||
return new WinmmOutput(block);
|
return new WinmmOutput(block);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &);
|
size_t Play(const void *chunk, size_t size);
|
||||||
void Drain();
|
void Drain();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
|
||||||
|
@ -153,8 +153,8 @@ WinmmOutput::WinmmOutput(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
void
|
||||||
WinmmOutput::Open(AudioFormat &audio_format, Error &)
|
WinmmOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
event = CreateEvent(nullptr, false, false, nullptr);
|
event = CreateEvent(nullptr, false, false, nullptr);
|
||||||
if (event == nullptr)
|
if (event == nullptr)
|
||||||
|
@ -199,8 +199,6 @@ WinmmOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
memset(&i.hdr, 0, sizeof(i.hdr));
|
memset(&i.hdr, 0, sizeof(i.hdr));
|
||||||
|
|
||||||
next_buffer = 0;
|
next_buffer = 0;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -260,7 +258,7 @@ WinmmOutput::DrainBuffer(WinmmBuffer &buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t
|
size_t
|
||||||
WinmmOutput::Play(const void *chunk, size_t size, Error &)
|
WinmmOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
/* get the next buffer from the ring and prepare it */
|
/* get the next buffer from the ring and prepare it */
|
||||||
WinmmBuffer *buffer = &buffers[next_buffer];
|
WinmmBuffer *buffer = &buffers[next_buffer];
|
||||||
|
|
|
@ -178,7 +178,7 @@ public:
|
||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
*/
|
*/
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Caller must lock the mutex.
|
* Caller must lock the mutex.
|
||||||
|
|
|
@ -118,7 +118,7 @@ HttpdOutput::Unbind()
|
||||||
}
|
}
|
||||||
|
|
||||||
static AudioOutput *
|
static AudioOutput *
|
||||||
httpd_output_init(const ConfigBlock &block, Error &)
|
httpd_output_init(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return *new HttpdOutput(io_thread_get(), block);
|
return *new HttpdOutput(io_thread_get(), block);
|
||||||
}
|
}
|
||||||
|
@ -247,13 +247,12 @@ HttpdOutput::ReadPage()
|
||||||
return Page::Copy(buffer, size);
|
return Page::Copy(buffer, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
httpd_output_enable(AudioOutput *ao, gcc_unused Error &error)
|
httpd_output_enable(AudioOutput *ao)
|
||||||
{
|
{
|
||||||
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
||||||
|
|
||||||
httpd->Bind();
|
httpd->Bind();
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -277,8 +276,8 @@ HttpdOutput::OpenEncoder(AudioFormat &audio_format)
|
||||||
unflushed_input = 0;
|
unflushed_input = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
HttpdOutput::Open(AudioFormat &audio_format, Error &)
|
HttpdOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
assert(!open);
|
assert(!open);
|
||||||
assert(clients.empty());
|
assert(clients.empty());
|
||||||
|
@ -290,18 +289,15 @@ HttpdOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
timer = new Timer(audio_format);
|
timer = new Timer(audio_format);
|
||||||
|
|
||||||
open = true;
|
open = true;
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
httpd_output_open(AudioOutput *ao, AudioFormat &audio_format,
|
httpd_output_open(AudioOutput *ao, AudioFormat &audio_format)
|
||||||
Error &error)
|
|
||||||
{
|
{
|
||||||
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
||||||
|
|
||||||
const ScopeLock protect(httpd->mutex);
|
const ScopeLock protect(httpd->mutex);
|
||||||
return httpd->Open(audio_format, error);
|
httpd->Open(audio_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -431,8 +427,7 @@ HttpdOutput::Play(const void *chunk, size_t size)
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
httpd_output_play(AudioOutput *ao, const void *chunk, size_t size,
|
httpd_output_play(AudioOutput *ao, const void *chunk, size_t size)
|
||||||
Error &)
|
|
||||||
{
|
{
|
||||||
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
HttpdOutput *httpd = HttpdOutput::Cast(ao);
|
||||||
|
|
||||||
|
|
|
@ -91,16 +91,16 @@ public:
|
||||||
return &base;
|
return &base;
|
||||||
}
|
}
|
||||||
|
|
||||||
static SlesOutput *Create(const ConfigBlock &block, Error &error);
|
static SlesOutput *Create(const ConfigBlock &block);
|
||||||
|
|
||||||
bool Open(AudioFormat &audio_format, Error &error);
|
void Open(AudioFormat &audio_format);
|
||||||
void Close();
|
void Close();
|
||||||
|
|
||||||
unsigned Delay() {
|
unsigned Delay() {
|
||||||
return pause && !cancel ? 100 : 0;
|
return pause && !cancel ? 100 : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t Play(const void *chunk, size_t size, Error &error);
|
size_t Play(const void *chunk, size_t size);
|
||||||
|
|
||||||
void Drain();
|
void Drain();
|
||||||
void Cancel();
|
void Cancel();
|
||||||
|
@ -129,8 +129,8 @@ SlesOutput::SlesOutput(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool
|
inline void
|
||||||
SlesOutput::Open(AudioFormat &audio_format, Error &)
|
SlesOutput::Open(AudioFormat &audio_format)
|
||||||
{
|
{
|
||||||
SLresult result;
|
SLresult result;
|
||||||
SLObjectItf _object;
|
SLObjectItf _object;
|
||||||
|
@ -146,7 +146,6 @@ SlesOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
if (result != SL_RESULT_SUCCESS) {
|
if (result != SL_RESULT_SUCCESS) {
|
||||||
engine_object.Destroy();
|
engine_object.Destroy();
|
||||||
throw std::runtime_error("Engine.Realize() failed");
|
throw std::runtime_error("Engine.Realize() failed");
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SLEngineItf _engine;
|
SLEngineItf _engine;
|
||||||
|
@ -294,7 +293,6 @@ SlesOutput::Open(AudioFormat &audio_format, Error &)
|
||||||
|
|
||||||
// TODO: support other sample formats
|
// TODO: support other sample formats
|
||||||
audio_format.format = SampleFormat::S16;
|
audio_format.format = SampleFormat::S16;
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void
|
||||||
|
@ -307,7 +305,7 @@ SlesOutput::Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t
|
inline size_t
|
||||||
SlesOutput::Play(const void *chunk, size_t size, Error &)
|
SlesOutput::Play(const void *chunk, size_t size)
|
||||||
{
|
{
|
||||||
cancel = false;
|
cancel = false;
|
||||||
|
|
||||||
|
@ -413,7 +411,7 @@ sles_test_default_device()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline SlesOutput *
|
inline SlesOutput *
|
||||||
SlesOutput::Create(const ConfigBlock &block, Error &)
|
SlesOutput::Create(const ConfigBlock &block)
|
||||||
{
|
{
|
||||||
return new SlesOutput(block);
|
return new SlesOutput(block);
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@
|
||||||
#include "Control.hxx"
|
#include "Control.hxx"
|
||||||
#include "Idle.hxx"
|
#include "Idle.hxx"
|
||||||
#include "DetachedSong.hxx"
|
#include "DetachedSong.hxx"
|
||||||
#include "util/Error.hxx"
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
|
@ -171,15 +170,6 @@ PlayerControl::SetError(PlayerError type, std::exception_ptr &&_error)
|
||||||
error = std::move(_error);
|
error = std::move(_error);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
|
||||||
PlayerControl::SetError(PlayerError type, Error &&_error)
|
|
||||||
{
|
|
||||||
assert(type != PlayerError::NONE);
|
|
||||||
assert(_error.IsDefined());
|
|
||||||
|
|
||||||
SetError(type, std::make_exception_ptr(std::move(_error)));
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
PlayerControl::LockClearError()
|
PlayerControl::LockClearError()
|
||||||
{
|
{
|
||||||
|
|
|
@ -355,9 +355,7 @@ public:
|
||||||
* Caller must lock the object.
|
* Caller must lock the object.
|
||||||
*
|
*
|
||||||
* @param type the error type; must not be #PlayerError::NONE
|
* @param type the error type; must not be #PlayerError::NONE
|
||||||
* @param error detailed error information; must be defined.
|
|
||||||
*/
|
*/
|
||||||
void SetError(PlayerError type, Error &&error);
|
|
||||||
void SetError(PlayerError type, std::exception_ptr &&_error);
|
void SetError(PlayerError type, std::exception_ptr &&_error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,7 +33,6 @@
|
||||||
#include "tag/Tag.hxx"
|
#include "tag/Tag.hxx"
|
||||||
#include "Idle.hxx"
|
#include "Idle.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
#include "util/Error.hxx"
|
|
||||||
#include "thread/Name.hxx"
|
#include "thread/Name.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,8 @@
|
||||||
#include "pcm/PcmConvert.hxx"
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "filter/FilterRegistry.hxx"
|
#include "filter/FilterRegistry.hxx"
|
||||||
#include "player/Control.hxx"
|
#include "player/Control.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/RuntimeError.hxx"
|
||||||
|
#include "util/ScopeExit.hxx"
|
||||||
#include "Log.hxx"
|
#include "Log.hxx"
|
||||||
|
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
@ -62,43 +63,29 @@ load_audio_output(EventLoop &event_loop, const char *name)
|
||||||
{
|
{
|
||||||
const auto *param = config_find_block(ConfigBlockOption::AUDIO_OUTPUT,
|
const auto *param = config_find_block(ConfigBlockOption::AUDIO_OUTPUT,
|
||||||
"name", name);
|
"name", name);
|
||||||
if (param == NULL) {
|
if (param == NULL)
|
||||||
fprintf(stderr, "No such configured audio output: %s\n", name);
|
throw FormatRuntimeError("No such configured audio output: %s\n",
|
||||||
return nullptr;
|
name);
|
||||||
}
|
|
||||||
|
|
||||||
static struct PlayerControl dummy_player_control(*(PlayerListener *)nullptr,
|
static struct PlayerControl dummy_player_control(*(PlayerListener *)nullptr,
|
||||||
*(MultipleOutputs *)nullptr,
|
*(MultipleOutputs *)nullptr,
|
||||||
32, 4);
|
32, 4);
|
||||||
|
|
||||||
Error error;
|
return audio_output_new(event_loop, *param,
|
||||||
AudioOutput *ao =
|
*(MixerListener *)nullptr,
|
||||||
audio_output_new(event_loop, *param,
|
dummy_player_control);
|
||||||
*(MixerListener *)nullptr,
|
|
||||||
dummy_player_control,
|
|
||||||
error);
|
|
||||||
if (ao == nullptr)
|
|
||||||
LogError(error);
|
|
||||||
|
|
||||||
return ao;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static void
|
||||||
run_output(AudioOutput *ao, AudioFormat audio_format)
|
run_output(AudioOutput *ao, AudioFormat audio_format)
|
||||||
{
|
{
|
||||||
/* open the audio output */
|
/* open the audio output */
|
||||||
|
|
||||||
Error error;
|
ao_plugin_enable(ao);
|
||||||
if (!ao_plugin_enable(ao, error)) {
|
AtScopeExit(ao) { ao_plugin_disable(ao); };
|
||||||
LogError(error, "Failed to enable audio output");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ao_plugin_open(ao, audio_format, error)) {
|
ao_plugin_open(ao, audio_format);
|
||||||
ao_plugin_disable(ao);
|
AtScopeExit(ao) { ao_plugin_close(ao); };
|
||||||
LogError(error, "Failed to open audio output");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct audio_format_string af_string;
|
struct audio_format_string af_string;
|
||||||
fprintf(stderr, "audio_format=%s\n",
|
fprintf(stderr, "audio_format=%s\n",
|
||||||
|
@ -123,14 +110,7 @@ run_output(AudioOutput *ao, AudioFormat audio_format)
|
||||||
size_t play_length = (length / frame_size) * frame_size;
|
size_t play_length = (length / frame_size) * frame_size;
|
||||||
if (play_length > 0) {
|
if (play_length > 0) {
|
||||||
size_t consumed = ao_plugin_play(ao,
|
size_t consumed = ao_plugin_play(ao,
|
||||||
buffer, play_length,
|
buffer, play_length);
|
||||||
error);
|
|
||||||
if (consumed == 0) {
|
|
||||||
ao_plugin_close(ao);
|
|
||||||
ao_plugin_disable(ao);
|
|
||||||
LogError(error, "Failed to play");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(consumed <= length);
|
assert(consumed <= length);
|
||||||
assert(consumed % frame_size == 0);
|
assert(consumed % frame_size == 0);
|
||||||
|
@ -139,16 +119,10 @@ run_output(AudioOutput *ao, AudioFormat audio_format)
|
||||||
memmove(buffer, buffer + consumed, length);
|
memmove(buffer, buffer + consumed, length);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ao_plugin_close(ao);
|
|
||||||
ao_plugin_disable(ao);
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
try {
|
try {
|
||||||
Error error;
|
|
||||||
|
|
||||||
if (argc < 3 || argc > 4) {
|
if (argc < 3 || argc > 4) {
|
||||||
fprintf(stderr, "Usage: run_output CONFIG NAME [FORMAT] <IN\n");
|
fprintf(stderr, "Usage: run_output CONFIG NAME [FORMAT] <IN\n");
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
@ -170,8 +144,6 @@ try {
|
||||||
/* initialize the audio output */
|
/* initialize the audio output */
|
||||||
|
|
||||||
AudioOutput *ao = load_audio_output(event_loop, argv[2]);
|
AudioOutput *ao = load_audio_output(event_loop, argv[2]);
|
||||||
if (ao == NULL)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* parse the audio format */
|
/* parse the audio format */
|
||||||
|
|
||||||
|
@ -180,7 +152,7 @@ try {
|
||||||
|
|
||||||
/* do it */
|
/* do it */
|
||||||
|
|
||||||
bool success = run_output(ao, audio_format);
|
run_output(ao, audio_format);
|
||||||
|
|
||||||
/* cleanup and exit */
|
/* cleanup and exit */
|
||||||
|
|
||||||
|
@ -188,7 +160,7 @@ try {
|
||||||
|
|
||||||
config_global_finish();
|
config_global_finish();
|
||||||
|
|
||||||
return success ? EXIT_SUCCESS : EXIT_FAILURE;
|
return EXIT_SUCCESS;
|
||||||
} catch (const std::exception &e) {
|
} catch (const std::exception &e) {
|
||||||
LogError(e);
|
LogError(e);
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
|
|
Loading…
Reference in New Issue