config/Param: split block-specific attributes to new struct ConfigBlock
The old struct config_param remains only for top-level string options.
This commit is contained in:
parent
84e74173de
commit
4fa5538e2b
@ -20,8 +20,12 @@
|
||||
#include "config.h"
|
||||
#include "Block.hxx"
|
||||
#include "ConfigParser.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
@ -57,3 +61,96 @@ BlockParam::GetBoolValue() const
|
||||
|
||||
return value2;
|
||||
}
|
||||
|
||||
ConfigBlock::~ConfigBlock()
|
||||
{
|
||||
delete next;
|
||||
}
|
||||
|
||||
const BlockParam *
|
||||
ConfigBlock::GetBlockParam(const char *name) const
|
||||
{
|
||||
for (const auto &i : block_params) {
|
||||
if (i.name == name) {
|
||||
i.used = true;
|
||||
return &i;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *
|
||||
ConfigBlock::GetBlockValue(const char *name, const char *default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->value.c_str();
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
ConfigBlock::GetBlockPath(const char *name, const char *default_value,
|
||||
Error &error) const
|
||||
{
|
||||
assert(!error.IsDefined());
|
||||
|
||||
int line2 = line;
|
||||
const char *s;
|
||||
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp != nullptr) {
|
||||
line2 = bp->line;
|
||||
s = bp->value.c_str();
|
||||
} else {
|
||||
if (default_value == nullptr)
|
||||
return AllocatedPath::Null();
|
||||
|
||||
s = default_value;
|
||||
}
|
||||
|
||||
AllocatedPath path = ParsePath(s, error);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
error.FormatPrefix("Invalid path in \"%s\" at line %i: ",
|
||||
name, line2);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
ConfigBlock::GetBlockPath(const char *name, Error &error) const
|
||||
{
|
||||
return GetBlockPath(name, nullptr, error);
|
||||
}
|
||||
|
||||
int
|
||||
ConfigBlock::GetBlockValue(const char *name, int default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetIntValue();
|
||||
}
|
||||
|
||||
unsigned
|
||||
ConfigBlock::GetBlockValue(const char *name, unsigned default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetUnsignedValue();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool
|
||||
ConfigBlock::GetBlockValue(const char *name, bool default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetBoolValue();
|
||||
}
|
||||
|
@ -21,9 +21,14 @@
|
||||
#define MPD_CONFIG_BLOCK_HXX
|
||||
|
||||
#include "check.h"
|
||||
#include "Param.hxx"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class Error;
|
||||
class AllocatedPath;
|
||||
|
||||
struct BlockParam {
|
||||
std::string name;
|
||||
@ -50,4 +55,71 @@ struct BlockParam {
|
||||
bool GetBoolValue() const;
|
||||
};
|
||||
|
||||
struct ConfigBlock {
|
||||
/**
|
||||
* The next #ConfigBlock with the same name. The destructor
|
||||
* deletes the whole chain.
|
||||
*/
|
||||
ConfigBlock *next;
|
||||
|
||||
int line;
|
||||
|
||||
std::vector<BlockParam> block_params;
|
||||
|
||||
/**
|
||||
* This flag is false when nobody has queried the value of
|
||||
* this option yet.
|
||||
*/
|
||||
bool used;
|
||||
|
||||
explicit ConfigBlock(int _line=-1)
|
||||
:next(nullptr), line(_line), used(false) {}
|
||||
|
||||
ConfigBlock(const ConfigBlock &) = delete;
|
||||
|
||||
~ConfigBlock();
|
||||
|
||||
ConfigBlock &operator=(const ConfigBlock &) = delete;
|
||||
|
||||
/**
|
||||
* Determine if this is a "null" instance, i.e. an empty
|
||||
* object that was synthesized and not loaded from a
|
||||
* configuration file.
|
||||
*/
|
||||
bool IsNull() const {
|
||||
return line < 0;
|
||||
}
|
||||
|
||||
gcc_nonnull_all
|
||||
void AddBlockParam(const char *_name, const char *_value,
|
||||
int _line=-1) {
|
||||
block_params.emplace_back(_name, _value, _line);
|
||||
}
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
const BlockParam *GetBlockParam(const char *_name) const;
|
||||
|
||||
gcc_pure
|
||||
const char *GetBlockValue(const char *name,
|
||||
const char *default_value=nullptr) const;
|
||||
|
||||
/**
|
||||
* Same as config_get_path(), but looks up the setting in the
|
||||
* specified block.
|
||||
*/
|
||||
AllocatedPath GetBlockPath(const char *name, const char *default_value,
|
||||
Error &error) const;
|
||||
|
||||
AllocatedPath GetBlockPath(const char *name, Error &error) const;
|
||||
|
||||
gcc_pure
|
||||
int GetBlockValue(const char *name, int default_value) const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetBlockValue(const char *name, unsigned default_value) const;
|
||||
|
||||
gcc_pure
|
||||
bool GetBlockValue(const char *name, bool default_value) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "ConfigFile.hxx"
|
||||
#include "Data.hxx"
|
||||
#include "Param.hxx"
|
||||
#include "Block.hxx"
|
||||
#include "ConfigTemplates.hxx"
|
||||
#include "util/Tokenizer.hxx"
|
||||
#include "util/StringUtil.hxx"
|
||||
@ -38,7 +39,7 @@ static constexpr char CONF_COMMENT = '#';
|
||||
static constexpr Domain config_file_domain("config_file");
|
||||
|
||||
static bool
|
||||
config_read_name_value(struct config_param *param, char *input, unsigned line,
|
||||
config_read_name_value(ConfigBlock &block, char *input, unsigned line,
|
||||
Error &error)
|
||||
{
|
||||
Tokenizer tokenizer(input);
|
||||
@ -65,7 +66,7 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
|
||||
return false;
|
||||
}
|
||||
|
||||
const BlockParam *bp = param->GetBlockParam(name);
|
||||
const BlockParam *bp = block.GetBlockParam(name);
|
||||
if (bp != nullptr) {
|
||||
error.Format(config_file_domain,
|
||||
"\"%s\" is duplicate, first defined on line %i",
|
||||
@ -73,14 +74,14 @@ config_read_name_value(struct config_param *param, char *input, unsigned line,
|
||||
return false;
|
||||
}
|
||||
|
||||
param->AddBlockParam(name, value, line);
|
||||
block.AddBlockParam(name, value, line);
|
||||
return true;
|
||||
}
|
||||
|
||||
static struct config_param *
|
||||
static ConfigBlock *
|
||||
config_read_block(BufferedReader &reader, Error &error)
|
||||
{
|
||||
struct config_param *ret = new config_param(reader.GetLineNumber());
|
||||
auto *ret = new ConfigBlock(reader.GetLineNumber());
|
||||
|
||||
while (true) {
|
||||
char *line = reader.ReadLine();
|
||||
@ -115,7 +116,7 @@ config_read_block(BufferedReader &reader, Error &error)
|
||||
|
||||
/* parse name and value */
|
||||
|
||||
if (!config_read_name_value(ret, line, reader.GetLineNumber(),
|
||||
if (!config_read_name_value(*ret, line, reader.GetLineNumber(),
|
||||
error)) {
|
||||
assert(*line != 0);
|
||||
delete ret;
|
||||
@ -125,6 +126,64 @@ config_read_block(BufferedReader &reader, Error &error)
|
||||
}
|
||||
}
|
||||
|
||||
gcc_nonnull_all
|
||||
static void
|
||||
Append(ConfigBlock *&head, ConfigBlock *p)
|
||||
{
|
||||
assert(p->next == nullptr);
|
||||
|
||||
auto **i = &head;
|
||||
while (*i != nullptr)
|
||||
i = &(*i)->next;
|
||||
|
||||
*i = p;
|
||||
}
|
||||
|
||||
static bool
|
||||
ReadConfigBlock(ConfigData &config_data, BufferedReader &reader,
|
||||
const char *name, ConfigOption o,
|
||||
Tokenizer &tokenizer,
|
||||
Error &error)
|
||||
{
|
||||
const unsigned i = unsigned(o);
|
||||
const ConfigTemplate &option = config_block_templates[i];
|
||||
ConfigBlock *&head = config_data.blocks[i];
|
||||
|
||||
if (head != nullptr && !option.repeatable) {
|
||||
ConfigBlock *block = head;
|
||||
error.Format(config_file_domain,
|
||||
"config parameter \"%s\" is first defined "
|
||||
"on line %d and redefined on line %u\n",
|
||||
name, block->line,
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
/* now parse the block or the value */
|
||||
|
||||
if (tokenizer.CurrentChar() != '{') {
|
||||
error.Format(config_file_domain,
|
||||
"line %u: '{' expected",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
char *line = StripLeft(tokenizer.Rest() + 1);
|
||||
if (*line != 0 && *line != CONF_COMMENT) {
|
||||
error.Format(config_file_domain,
|
||||
"line %u: Unknown tokens after '{'",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *param = config_read_block(reader, error);
|
||||
if (param == nullptr)
|
||||
return false;
|
||||
|
||||
Append(head, param);
|
||||
return true;
|
||||
}
|
||||
|
||||
gcc_nonnull_all
|
||||
static void
|
||||
Append(config_param *&head, config_param *p)
|
||||
@ -145,7 +204,7 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader,
|
||||
Error &error)
|
||||
{
|
||||
const unsigned i = unsigned(o);
|
||||
const ConfigTemplate &option = config_templates[i];
|
||||
const ConfigTemplate &option = config_param_templates[i];
|
||||
config_param *&head = config_data.params[i];
|
||||
|
||||
if (head != nullptr && !option.repeatable) {
|
||||
@ -160,57 +219,28 @@ ReadConfigParam(ConfigData &config_data, BufferedReader &reader,
|
||||
|
||||
/* now parse the block or the value */
|
||||
|
||||
struct config_param *param;
|
||||
if (option.block) {
|
||||
/* it's a block, call config_read_block() */
|
||||
|
||||
if (tokenizer.CurrentChar() != '{') {
|
||||
const char *value = tokenizer.NextString(error);
|
||||
if (value == nullptr) {
|
||||
if (tokenizer.IsEnd())
|
||||
error.Format(config_file_domain,
|
||||
"line %u: '{' expected",
|
||||
"line %u: Value missing",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
else
|
||||
error.FormatPrefix("line %u: ",
|
||||
reader.GetLineNumber());
|
||||
|
||||
char *line = StripLeft(tokenizer.Rest() + 1);
|
||||
if (*line != 0 && *line != CONF_COMMENT) {
|
||||
error.Format(config_file_domain,
|
||||
"line %u: Unknown tokens after '{'",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
param = config_read_block(reader, error);
|
||||
if (param == nullptr) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
/* a string value */
|
||||
|
||||
const char *value = tokenizer.NextString(error);
|
||||
if (value == nullptr) {
|
||||
if (tokenizer.IsEnd())
|
||||
error.Format(config_file_domain,
|
||||
"line %u: Value missing",
|
||||
reader.GetLineNumber());
|
||||
else
|
||||
error.FormatPrefix("line %u: ",
|
||||
reader.GetLineNumber());
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tokenizer.IsEnd() &&
|
||||
tokenizer.CurrentChar() != CONF_COMMENT) {
|
||||
error.Format(config_file_domain,
|
||||
"line %u: Unknown tokens after value",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
param = new config_param(value,
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!tokenizer.IsEnd() &&
|
||||
tokenizer.CurrentChar() != CONF_COMMENT) {
|
||||
error.Format(config_file_domain,
|
||||
"line %u: Unknown tokens after value",
|
||||
reader.GetLineNumber());
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *param = new config_param(value, reader.GetLineNumber());
|
||||
Append(head, param);
|
||||
return true;
|
||||
}
|
||||
@ -242,10 +272,15 @@ ReadConfigFile(ConfigData &config_data, BufferedReader &reader, Error &error)
|
||||
"repeatable" flag */
|
||||
|
||||
const ConfigOption o = ParseConfigOptionName(name);
|
||||
ConfigBlockOption bo;
|
||||
if (o != ConfigOption::MAX) {
|
||||
if (!ReadConfigParam(config_data, reader, name, o,
|
||||
tokenizer, error))
|
||||
return false;
|
||||
} else if ((bo = ParseConfigBlockOptionName(name)) != ConfigBlockOption::MAX) {
|
||||
if (!ReadConfigBlock(config_data, reader, name, o,
|
||||
tokenizer, error))
|
||||
return false;
|
||||
} else {
|
||||
error.Format(config_file_domain,
|
||||
"unrecognized parameter in config file at "
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "ConfigParser.hxx"
|
||||
#include "Data.hxx"
|
||||
#include "Param.hxx"
|
||||
#include "Block.hxx"
|
||||
#include "ConfigFile.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "ConfigError.hxx"
|
||||
@ -51,15 +52,15 @@ ReadConfigFile(Path path, Error &error)
|
||||
}
|
||||
|
||||
static void
|
||||
Check(const config_param *param)
|
||||
Check(const ConfigBlock &block)
|
||||
{
|
||||
if (!param->used)
|
||||
/* this whole config_param was not queried at all -
|
||||
if (!block.used)
|
||||
/* this whole block was not queried at all -
|
||||
the feature might be disabled at compile time?
|
||||
Silently ignore it here. */
|
||||
return;
|
||||
|
||||
for (const auto &i : param->block_params) {
|
||||
for (const auto &i : block.block_params) {
|
||||
if (!i.used)
|
||||
FormatWarning(config_domain,
|
||||
"option '%s' on line %i was not recognized",
|
||||
@ -69,9 +70,9 @@ Check(const config_param *param)
|
||||
|
||||
void config_global_check(void)
|
||||
{
|
||||
for (auto i : config_data.params)
|
||||
for (const config_param *p = i; p != nullptr; p = p->next)
|
||||
Check(p);
|
||||
for (auto i : config_data.blocks)
|
||||
for (const auto *p = i; p != nullptr; p = p->next)
|
||||
Check(*p);
|
||||
}
|
||||
|
||||
const config_param *
|
||||
@ -83,18 +84,27 @@ config_get_param(ConfigOption option)
|
||||
return param;
|
||||
}
|
||||
|
||||
const config_param *
|
||||
config_find_block(ConfigOption option, const char *key, const char *value)
|
||||
const ConfigBlock *
|
||||
config_get_block(ConfigBlockOption option)
|
||||
{
|
||||
for (const config_param *param = config_get_param(option);
|
||||
param != nullptr; param = param->next) {
|
||||
const char *value2 = param->GetBlockValue(key);
|
||||
ConfigBlock *block = config_data.blocks[unsigned(option)];
|
||||
if (block != nullptr)
|
||||
block->used = true;
|
||||
return block;
|
||||
}
|
||||
|
||||
const ConfigBlock *
|
||||
config_find_block(ConfigBlockOption option, const char *key, const char *value)
|
||||
{
|
||||
for (const auto *block = config_get_block(option);
|
||||
block != nullptr; block = block->next) {
|
||||
const char *value2 = block->GetBlockValue(key);
|
||||
if (value2 == nullptr)
|
||||
FormatFatalError("block without '%s' name in line %d",
|
||||
key, param->line);
|
||||
key, block->line);
|
||||
|
||||
if (strcmp(value2, value) == 0)
|
||||
return param;
|
||||
return block;
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
@ -27,6 +27,7 @@ class Error;
|
||||
class Path;
|
||||
class AllocatedPath;
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
|
||||
void config_global_init(void);
|
||||
void config_global_finish(void);
|
||||
@ -44,6 +45,10 @@ gcc_pure
|
||||
const config_param *
|
||||
config_get_param(enum ConfigOption option);
|
||||
|
||||
gcc_pure
|
||||
const ConfigBlock *
|
||||
config_get_block(enum ConfigBlockOption option);
|
||||
|
||||
/**
|
||||
* Find a block with a matching attribute.
|
||||
*
|
||||
@ -52,8 +57,8 @@ config_get_param(enum ConfigOption option);
|
||||
* @param value the expected attribute value
|
||||
*/
|
||||
gcc_pure
|
||||
const config_param *
|
||||
config_find_block(ConfigOption option, const char *key, const char *value);
|
||||
const ConfigBlock *
|
||||
config_find_block(ConfigBlockOption option, const char *key, const char *value);
|
||||
|
||||
/* Note on gcc_pure: Some of the functions declared pure are not
|
||||
really pure in strict sense. They have side effect such that they
|
||||
|
@ -49,7 +49,6 @@ enum class ConfigOption {
|
||||
ZEROCONF_ENABLED,
|
||||
PASSWORD,
|
||||
DEFAULT_PERMS,
|
||||
AUDIO_OUTPUT,
|
||||
AUDIO_OUTPUT_FORMAT,
|
||||
MIXER_TYPE,
|
||||
REPLAYGAIN,
|
||||
@ -73,15 +72,20 @@ enum class ConfigOption {
|
||||
ID3V1_ENCODING,
|
||||
METADATA_TO_USE,
|
||||
SAVE_ABSOLUTE_PATHS,
|
||||
DECODER,
|
||||
INPUT,
|
||||
GAPLESS_MP3_PLAYBACK,
|
||||
PLAYLIST_PLUGIN,
|
||||
AUTO_UPDATE,
|
||||
AUTO_UPDATE_DEPTH,
|
||||
DESPOTIFY_USER,
|
||||
DESPOTIFY_PASSWORD,
|
||||
DESPOTIFY_HIGH_BITRATE,
|
||||
MAX
|
||||
};
|
||||
|
||||
enum class ConfigBlockOption {
|
||||
AUDIO_OUTPUT,
|
||||
DECODER,
|
||||
INPUT,
|
||||
PLAYLIST_PLUGIN,
|
||||
AUDIO_FILTER,
|
||||
DATABASE,
|
||||
NEIGHBORS,
|
||||
@ -99,4 +103,11 @@ gcc_pure
|
||||
enum ConfigOption
|
||||
ParseConfigOptionName(const char *name);
|
||||
|
||||
/**
|
||||
* @return #ConfigOption::MAX if not found
|
||||
*/
|
||||
gcc_pure
|
||||
enum ConfigBlockOption
|
||||
ParseConfigBlockOptionName(const char *name);
|
||||
|
||||
#endif
|
||||
|
@ -23,76 +23,105 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
const ConfigTemplate config_templates[] = {
|
||||
{ "music_directory", false, false },
|
||||
{ "playlist_directory", false, false },
|
||||
{ "follow_inside_symlinks", false, false },
|
||||
{ "follow_outside_symlinks", false, false },
|
||||
{ "db_file", false, false },
|
||||
{ "sticker_file", false, false },
|
||||
{ "log_file", false, false },
|
||||
{ "pid_file", false, false },
|
||||
{ "state_file", false, false },
|
||||
{ "state_file_interval", false, false },
|
||||
{ "restore_paused", false, false },
|
||||
{ "user", false, false },
|
||||
{ "group", false, false },
|
||||
{ "bind_to_address", true, false },
|
||||
{ "port", false, false },
|
||||
{ "log_level", false, false },
|
||||
{ "zeroconf_name", false, false },
|
||||
{ "zeroconf_enabled", false, false },
|
||||
{ "password", true, false },
|
||||
{ "default_permissions", false, false },
|
||||
{ "audio_output", true, true },
|
||||
{ "audio_output_format", false, false },
|
||||
{ "mixer_type", false, false },
|
||||
{ "replaygain", false, false },
|
||||
{ "replaygain_preamp", false, false },
|
||||
{ "replaygain_missing_preamp", false, false },
|
||||
{ "replaygain_limit", false, false },
|
||||
{ "volume_normalization", false, false },
|
||||
{ "samplerate_converter", false, false },
|
||||
{ "audio_buffer_size", false, false },
|
||||
{ "buffer_before_play", false, false },
|
||||
{ "http_proxy_host", false, false },
|
||||
{ "http_proxy_port", false, false },
|
||||
{ "http_proxy_user", false, false },
|
||||
{ "http_proxy_password", false, false },
|
||||
{ "connection_timeout", false, false },
|
||||
{ "max_connections", false, false },
|
||||
{ "max_playlist_length", false, false },
|
||||
{ "max_command_list_size", false, false },
|
||||
{ "max_output_buffer_size", false, false },
|
||||
{ "filesystem_charset", false, false },
|
||||
{ "id3v1_encoding", false, false },
|
||||
{ "metadata_to_use", false, false },
|
||||
{ "save_absolute_paths_in_playlists", false, false },
|
||||
{ "decoder", true, true },
|
||||
{ "input", true, true },
|
||||
{ "gapless_mp3_playback", false, false },
|
||||
{ "playlist_plugin", true, true },
|
||||
{ "auto_update", false, false },
|
||||
{ "auto_update_depth", false, false },
|
||||
{ "despotify_user", false, false },
|
||||
{ "despotify_password", false, false},
|
||||
{ "despotify_high_bitrate", false, false },
|
||||
{ "filter", true, true },
|
||||
{ "database", false, true },
|
||||
{ "neighbors", true, true },
|
||||
const ConfigTemplate config_param_templates[] = {
|
||||
{ "music_directory", false },
|
||||
{ "playlist_directory", false },
|
||||
{ "follow_inside_symlinks", false },
|
||||
{ "follow_outside_symlinks", false },
|
||||
{ "db_file", false },
|
||||
{ "sticker_file", false },
|
||||
{ "log_file", false },
|
||||
{ "pid_file", false },
|
||||
{ "state_file", false },
|
||||
{ "state_file_interval", false },
|
||||
{ "restore_paused", false },
|
||||
{ "user", false },
|
||||
{ "group", false },
|
||||
{ "bind_to_address", true },
|
||||
{ "port", false },
|
||||
{ "log_level", false },
|
||||
{ "zeroconf_name", false },
|
||||
{ "zeroconf_enabled", false },
|
||||
{ "password", true },
|
||||
{ "default_permissions", false },
|
||||
{ "audio_output_format", false },
|
||||
{ "mixer_type", false },
|
||||
{ "replaygain", false },
|
||||
{ "replaygain_preamp", false },
|
||||
{ "replaygain_missing_preamp", false },
|
||||
{ "replaygain_limit", false },
|
||||
{ "volume_normalization", false },
|
||||
{ "samplerate_converter", false },
|
||||
{ "audio_buffer_size", false },
|
||||
{ "buffer_before_play", false },
|
||||
{ "http_proxy_host", false },
|
||||
{ "http_proxy_port", false },
|
||||
{ "http_proxy_user", false },
|
||||
{ "http_proxy_password", false },
|
||||
{ "connection_timeout", false },
|
||||
{ "max_connections", false },
|
||||
{ "max_playlist_length", false },
|
||||
{ "max_command_list_size", false },
|
||||
{ "max_output_buffer_size", false },
|
||||
{ "filesystem_charset", false },
|
||||
{ "id3v1_encoding", false },
|
||||
{ "metadata_to_use", false },
|
||||
{ "save_absolute_paths_in_playlists", false },
|
||||
{ "gapless_mp3_playback", false },
|
||||
{ "auto_update", false },
|
||||
{ "auto_update_depth", false },
|
||||
{ "despotify_user", false },
|
||||
{ "despotify_password", false },
|
||||
{ "despotify_high_bitrate", false },
|
||||
};
|
||||
|
||||
static constexpr unsigned n_config_templates = ARRAY_SIZE(config_templates);
|
||||
static constexpr unsigned n_config_param_templates =
|
||||
ARRAY_SIZE(config_param_templates);
|
||||
|
||||
static_assert(n_config_templates == unsigned(ConfigOption::MAX),
|
||||
"Wrong number of config_templates");
|
||||
static_assert(n_config_param_templates == unsigned(ConfigOption::MAX),
|
||||
"Wrong number of config_param_templates");
|
||||
|
||||
const ConfigTemplate config_block_templates[] = {
|
||||
{ "audio_output", true },
|
||||
{ "decoder", true },
|
||||
{ "input", true },
|
||||
{ "playlist_plugin", true },
|
||||
{ "filter", true },
|
||||
{ "database", false },
|
||||
{ "neighbors", true },
|
||||
};
|
||||
|
||||
static constexpr unsigned n_config_block_templates =
|
||||
ARRAY_SIZE(config_block_templates);
|
||||
|
||||
static_assert(n_config_block_templates == unsigned(ConfigBlockOption::MAX),
|
||||
"Wrong number of config_block_templates");
|
||||
|
||||
gcc_pure
|
||||
static inline unsigned
|
||||
ParseConfigTemplateName(const ConfigTemplate templates[], unsigned count,
|
||||
const char *name)
|
||||
{
|
||||
unsigned i = 0;
|
||||
for (; i < count; ++i)
|
||||
if (strcmp(templates[i].name, name) == 0)
|
||||
break;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ConfigOption
|
||||
ParseConfigOptionName(const char *name)
|
||||
{
|
||||
for (unsigned i = 0; i < n_config_templates; ++i)
|
||||
if (strcmp(config_templates[i].name, name) == 0)
|
||||
return ConfigOption(i);
|
||||
|
||||
return ConfigOption::MAX;
|
||||
return ConfigOption(ParseConfigTemplateName(config_param_templates,
|
||||
n_config_param_templates,
|
||||
name));
|
||||
}
|
||||
|
||||
ConfigBlockOption
|
||||
ParseConfigBlockOptionName(const char *name)
|
||||
{
|
||||
return ConfigBlockOption(ParseConfigTemplateName(config_block_templates,
|
||||
n_config_block_templates,
|
||||
name));
|
||||
}
|
||||
|
@ -23,9 +23,9 @@
|
||||
struct ConfigTemplate {
|
||||
const char *const name;
|
||||
const bool repeatable;
|
||||
const bool block;
|
||||
};
|
||||
|
||||
extern const ConfigTemplate config_templates[];
|
||||
extern const ConfigTemplate config_param_templates[];
|
||||
extern const ConfigTemplate config_block_templates[];
|
||||
|
||||
#endif
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "Data.hxx"
|
||||
#include "Param.hxx"
|
||||
#include "Block.hxx"
|
||||
|
||||
void
|
||||
ConfigData::Clear()
|
||||
@ -28,4 +29,9 @@ ConfigData::Clear()
|
||||
delete i;
|
||||
i = nullptr;
|
||||
}
|
||||
|
||||
for (auto &i : blocks) {
|
||||
delete i;
|
||||
i = nullptr;
|
||||
}
|
||||
}
|
||||
|
@ -25,9 +25,11 @@
|
||||
#include <array>
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
|
||||
struct ConfigData {
|
||||
std::array<config_param *, std::size_t(ConfigOption::MAX)> params;
|
||||
std::array<ConfigBlock *, std::size_t(ConfigBlockOption::MAX)> blocks;
|
||||
|
||||
void Clear();
|
||||
};
|
||||
|
@ -19,12 +19,6 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "Param.hxx"
|
||||
#include "ConfigPath.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
config_param::config_param(const char *_value, int _line)
|
||||
:next(nullptr), value(_value), line(_line), used(false) {}
|
||||
@ -33,91 +27,3 @@ config_param::~config_param()
|
||||
{
|
||||
delete next;
|
||||
}
|
||||
|
||||
const BlockParam *
|
||||
config_param::GetBlockParam(const char *name) const
|
||||
{
|
||||
for (const auto &i : block_params) {
|
||||
if (i.name == name) {
|
||||
i.used = true;
|
||||
return &i;
|
||||
}
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const char *
|
||||
config_param::GetBlockValue(const char *name, const char *default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->value.c_str();
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
config_param::GetBlockPath(const char *name, const char *default_value,
|
||||
Error &error) const
|
||||
{
|
||||
assert(!error.IsDefined());
|
||||
|
||||
int line2 = line;
|
||||
const char *s;
|
||||
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp != nullptr) {
|
||||
line2 = bp->line;
|
||||
s = bp->value.c_str();
|
||||
} else {
|
||||
if (default_value == nullptr)
|
||||
return AllocatedPath::Null();
|
||||
|
||||
s = default_value;
|
||||
}
|
||||
|
||||
AllocatedPath path = ParsePath(s, error);
|
||||
if (gcc_unlikely(path.IsNull()))
|
||||
error.FormatPrefix("Invalid path in \"%s\" at line %i: ",
|
||||
name, line2);
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
AllocatedPath
|
||||
config_param::GetBlockPath(const char *name, Error &error) const
|
||||
{
|
||||
return GetBlockPath(name, nullptr, error);
|
||||
}
|
||||
|
||||
int
|
||||
config_param::GetBlockValue(const char *name, int default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetIntValue();
|
||||
}
|
||||
|
||||
unsigned
|
||||
config_param::GetBlockValue(const char *name, unsigned default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetUnsignedValue();
|
||||
}
|
||||
|
||||
gcc_pure
|
||||
bool
|
||||
config_param::GetBlockValue(const char *name, bool default_value) const
|
||||
{
|
||||
const BlockParam *bp = GetBlockParam(name);
|
||||
if (bp == nullptr)
|
||||
return default_value;
|
||||
|
||||
return bp->GetBoolValue();
|
||||
}
|
||||
|
@ -20,14 +20,10 @@
|
||||
#ifndef MPD_CONFIG_PARAM_HXX
|
||||
#define MPD_CONFIG_PARAM_HXX
|
||||
|
||||
#include "Block.hxx"
|
||||
#include "check.h"
|
||||
#include "Compiler.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class AllocatedPath;
|
||||
class Error;
|
||||
|
||||
struct config_param {
|
||||
/**
|
||||
@ -40,8 +36,6 @@ struct config_param {
|
||||
|
||||
int line;
|
||||
|
||||
std::vector<BlockParam> block_params;
|
||||
|
||||
/**
|
||||
* This flag is false when nobody has queried the value of
|
||||
* this option yet.
|
||||
@ -68,37 +62,6 @@ struct config_param {
|
||||
bool IsNull() const {
|
||||
return line < 0;
|
||||
}
|
||||
|
||||
gcc_nonnull_all
|
||||
void AddBlockParam(const char *_name, const char *_value,
|
||||
int _line=-1) {
|
||||
block_params.emplace_back(_name, _value, _line);
|
||||
}
|
||||
|
||||
gcc_nonnull_all gcc_pure
|
||||
const BlockParam *GetBlockParam(const char *_name) const;
|
||||
|
||||
gcc_pure
|
||||
const char *GetBlockValue(const char *name,
|
||||
const char *default_value=nullptr) const;
|
||||
|
||||
/**
|
||||
* Same as config_get_path(), but looks up the setting in the
|
||||
* specified block.
|
||||
*/
|
||||
AllocatedPath GetBlockPath(const char *name, const char *default_value,
|
||||
Error &error) const;
|
||||
|
||||
AllocatedPath GetBlockPath(const char *name, Error &error) const;
|
||||
|
||||
gcc_pure
|
||||
int GetBlockValue(const char *name, int default_value) const;
|
||||
|
||||
gcc_pure
|
||||
unsigned GetBlockValue(const char *name, unsigned default_value) const;
|
||||
|
||||
gcc_pure
|
||||
bool GetBlockValue(const char *name, bool default_value) const;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "DatabaseGlue.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "fs/StandardDirectory.hxx"
|
||||
@ -32,7 +33,7 @@ Database *
|
||||
CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
|
||||
Error &error)
|
||||
{
|
||||
const auto *param = config_get_param(ConfigOption::DATABASE);
|
||||
const auto *param = config_get_block(ConfigBlockOption::DATABASE);
|
||||
const auto *path = config_get_param(ConfigOption::DB_FILE);
|
||||
|
||||
if (param != nullptr && path != nullptr) {
|
||||
@ -42,10 +43,10 @@ CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
struct config_param *allocated = nullptr;
|
||||
ConfigBlock *allocated = nullptr;
|
||||
|
||||
if (param == nullptr && path != nullptr) {
|
||||
allocated = new config_param("database", path->line);
|
||||
allocated = new ConfigBlock(path->line);
|
||||
allocated->AddBlockParam("path", path->value.c_str(),
|
||||
path->line);
|
||||
param = allocated;
|
||||
@ -60,7 +61,7 @@ CreateConfiguredDatabase(EventLoop &loop, DatabaseListener &listener,
|
||||
|
||||
const auto db_file = AllocatedPath::Build(cache_dir, "mpd.db");
|
||||
|
||||
allocated = new config_param("database");
|
||||
allocated = new ConfigBlock();
|
||||
allocated->AddBlockParam("path", db_file.c_str(), -1);
|
||||
param = allocated;
|
||||
}
|
||||
|
@ -22,17 +22,17 @@
|
||||
#include "Registry.hxx"
|
||||
#include "DatabaseError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "DatabasePlugin.hxx"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
Database *
|
||||
DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *plugin_name =
|
||||
param.GetBlockValue("plugin", "simple");
|
||||
block.GetBlockValue("plugin", "simple");
|
||||
|
||||
const DatabasePlugin *plugin = GetDatabasePluginByName(plugin_name);
|
||||
if (plugin == nullptr) {
|
||||
@ -41,5 +41,5 @@ DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return plugin->create(loop, listener, param, error);
|
||||
return plugin->create(loop, listener, block, error);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class EventLoop;
|
||||
class DatabaseListener;
|
||||
class Database;
|
||||
@ -35,6 +35,6 @@ class Error;
|
||||
*/
|
||||
Database *
|
||||
DatabaseGlobalInit(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m, Error &error);
|
||||
const ConfigBlock &block, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef MPD_DATABASE_PLUGIN_HXX
|
||||
#define MPD_DATABASE_PLUGIN_HXX
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class Error;
|
||||
class EventLoop;
|
||||
class DatabaseListener;
|
||||
@ -47,7 +47,7 @@ struct DatabasePlugin {
|
||||
* Allocates and configures a database.
|
||||
*/
|
||||
Database *(*create)(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
constexpr bool RequireStorage() const {
|
||||
|
@ -30,7 +30,7 @@
|
||||
#include "db/Stats.hxx"
|
||||
#include "SongFilter.hxx"
|
||||
#include "Compiler.h"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "util/Error.hxx"
|
||||
@ -97,7 +97,7 @@ public:
|
||||
listener(_listener) {}
|
||||
|
||||
static Database *Create(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
virtual bool Open(Error &error) override;
|
||||
@ -129,7 +129,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Connect(Error &error);
|
||||
bool CheckConnection(Error &error);
|
||||
@ -321,10 +321,10 @@ SendConstraints(mpd_connection *connection, const DatabaseSelection &selection)
|
||||
|
||||
Database *
|
||||
ProxyDatabase::Create(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
ProxyDatabase *db = new ProxyDatabase(loop, listener);
|
||||
if (!db->Configure(param, error)) {
|
||||
if (!db->Configure(block, error)) {
|
||||
delete db;
|
||||
db = nullptr;
|
||||
}
|
||||
@ -333,11 +333,11 @@ ProxyDatabase::Create(EventLoop &loop, DatabaseListener &listener,
|
||||
}
|
||||
|
||||
bool
|
||||
ProxyDatabase::Configure(const config_param ¶m, gcc_unused Error &error)
|
||||
ProxyDatabase::Configure(const ConfigBlock &block, gcc_unused Error &error)
|
||||
{
|
||||
host = param.GetBlockValue("host", "");
|
||||
port = param.GetBlockValue("port", 0u);
|
||||
keepalive = param.GetBlockValue("keepalive", false);
|
||||
host = block.GetBlockValue("host", "");
|
||||
port = block.GetBlockValue("port", 0u);
|
||||
keepalive = block.GetBlockValue("keepalive", false);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -34,7 +34,7 @@
|
||||
#include "fs/io/TextFile.hxx"
|
||||
#include "fs/io/BufferedOutputStream.hxx"
|
||||
#include "fs/io/FileOutputStream.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "fs/FileSystem.hxx"
|
||||
#include "util/CharUtil.hxx"
|
||||
#include "util/Error.hxx"
|
||||
@ -76,10 +76,10 @@ inline SimpleDatabase::SimpleDatabase(AllocatedPath &&_path,
|
||||
Database *
|
||||
SimpleDatabase::Create(gcc_unused EventLoop &loop,
|
||||
gcc_unused DatabaseListener &listener,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
SimpleDatabase *db = new SimpleDatabase();
|
||||
if (!db->Configure(param, error)) {
|
||||
if (!db->Configure(block, error)) {
|
||||
delete db;
|
||||
db = nullptr;
|
||||
}
|
||||
@ -88,9 +88,9 @@ SimpleDatabase::Create(gcc_unused EventLoop &loop,
|
||||
}
|
||||
|
||||
bool
|
||||
SimpleDatabase::Configure(const config_param ¶m, Error &error)
|
||||
SimpleDatabase::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
path = param.GetBlockPath("path", error);
|
||||
path = block.GetBlockPath("path", error);
|
||||
if (path.IsNull()) {
|
||||
if (!error.IsDefined())
|
||||
error.Set(simple_db_domain,
|
||||
@ -100,12 +100,12 @@ SimpleDatabase::Configure(const config_param ¶m, Error &error)
|
||||
|
||||
path_utf8 = path.ToUTF8();
|
||||
|
||||
cache_path = param.GetBlockPath("cache_directory", error);
|
||||
cache_path = block.GetBlockPath("cache_directory", error);
|
||||
if (path.IsNull() && error.IsDefined())
|
||||
return false;
|
||||
|
||||
#ifdef ENABLE_ZLIB
|
||||
compress = param.GetBlockValue("compress", compress);
|
||||
compress = block.GetBlockValue("compress", compress);
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
@ -28,7 +28,7 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
struct Directory;
|
||||
struct DatabasePlugin;
|
||||
class EventLoop;
|
||||
@ -73,7 +73,7 @@ class SimpleDatabase : public Database {
|
||||
|
||||
public:
|
||||
static Database *Create(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
gcc_pure
|
||||
@ -134,7 +134,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
gcc_pure
|
||||
bool Check(Error &error) const;
|
||||
|
@ -33,7 +33,7 @@
|
||||
#include "db/LightDirectory.hxx"
|
||||
#include "db/LightSong.hxx"
|
||||
#include "db/Stats.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "tag/TagTable.hxx"
|
||||
#include "util/Error.hxx"
|
||||
@ -78,7 +78,7 @@ public:
|
||||
UpnpDatabase():Database(upnp_db_plugin) {}
|
||||
|
||||
static Database *Create(EventLoop &loop, DatabaseListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
virtual bool Open(Error &error) override;
|
||||
@ -106,7 +106,7 @@ public:
|
||||
}
|
||||
|
||||
protected:
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
private:
|
||||
bool VisitServer(const ContentDirectoryService &server,
|
||||
@ -158,10 +158,10 @@ private:
|
||||
Database *
|
||||
UpnpDatabase::Create(gcc_unused EventLoop &loop,
|
||||
gcc_unused DatabaseListener &listener,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
UpnpDatabase *db = new UpnpDatabase();
|
||||
if (!db->Configure(param, error)) {
|
||||
if (!db->Configure(block, error)) {
|
||||
delete db;
|
||||
return nullptr;
|
||||
}
|
||||
@ -173,7 +173,7 @@ UpnpDatabase::Create(gcc_unused EventLoop &loop,
|
||||
}
|
||||
|
||||
inline bool
|
||||
UpnpDatabase::Configure(const config_param &, Error &)
|
||||
UpnpDatabase::Configure(const ConfigBlock &, Error &)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@
|
||||
#include "tag/Tag.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "MixRampInfo.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "Chrono.hxx"
|
||||
|
||||
// IWYU pragma: end_exports
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include "DecoderList.hxx"
|
||||
#include "DecoderPlugin.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "plugins/AudiofileDecoderPlugin.hxx"
|
||||
#include "plugins/PcmDecoderPlugin.hxx"
|
||||
#include "plugins/DsdiffDecoderPlugin.hxx"
|
||||
@ -127,12 +127,12 @@ decoder_plugin_from_name(const char *name)
|
||||
|
||||
void decoder_plugin_init_all(void)
|
||||
{
|
||||
struct config_param empty;
|
||||
ConfigBlock empty;
|
||||
|
||||
for (unsigned i = 0; decoder_plugins[i] != nullptr; ++i) {
|
||||
const DecoderPlugin &plugin = *decoder_plugins[i];
|
||||
const struct config_param *param =
|
||||
config_find_block(ConfigOption::DECODER, "plugin",
|
||||
const auto *param =
|
||||
config_find_block(ConfigBlockOption::DECODER, "plugin",
|
||||
plugin.name);
|
||||
|
||||
if (param == nullptr)
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
#include "Compiler.h"
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class InputStream;
|
||||
struct tag_handler;
|
||||
class Path;
|
||||
@ -44,7 +44,7 @@ struct DecoderPlugin {
|
||||
* @return true if the plugin was initialized successfully,
|
||||
* false if the plugin is not available
|
||||
*/
|
||||
bool (*init)(const config_param ¶m);
|
||||
bool (*init)(const ConfigBlock &block);
|
||||
|
||||
/**
|
||||
* Deinitialize a decoder plugin which was initialized
|
||||
@ -112,9 +112,9 @@ struct DecoderPlugin {
|
||||
* @return true if the plugin was initialized successfully, false if
|
||||
* the plugin is not available
|
||||
*/
|
||||
bool Init(const config_param ¶m) const {
|
||||
bool Init(const ConfigBlock &block) const {
|
||||
return init != nullptr
|
||||
? init(param)
|
||||
? init(block)
|
||||
: true;
|
||||
}
|
||||
|
||||
|
@ -38,14 +38,14 @@ static constexpr Domain adplug_domain("adplug");
|
||||
static unsigned sample_rate;
|
||||
|
||||
static bool
|
||||
adplug_init(const config_param ¶m)
|
||||
adplug_init(const ConfigBlock &block)
|
||||
{
|
||||
FormatDebug(adplug_domain, "adplug %s",
|
||||
CAdPlug::get_version().c_str());
|
||||
|
||||
Error error;
|
||||
|
||||
sample_rate = param.GetBlockValue("sample_rate", 48000u);
|
||||
sample_rate = block.GetBlockValue("sample_rate", 48000u);
|
||||
if (!audio_check_sample_rate(sample_rate, error)) {
|
||||
LogError(error);
|
||||
return false;
|
||||
|
@ -43,7 +43,7 @@ audiofile_error_func(long, const char *msg)
|
||||
}
|
||||
|
||||
static bool
|
||||
audiofile_init(const config_param &)
|
||||
audiofile_init(const ConfigBlock &)
|
||||
{
|
||||
afSetErrorHandler(audiofile_error_func);
|
||||
return true;
|
||||
|
@ -72,9 +72,9 @@ struct DsdiffMetaData {
|
||||
static bool lsbitfirst;
|
||||
|
||||
static bool
|
||||
dsdiff_init(const config_param ¶m)
|
||||
dsdiff_init(const ConfigBlock &block)
|
||||
{
|
||||
lsbitfirst = param.GetBlockValue("lsbitfirst", false);
|
||||
lsbitfirst = block.GetBlockValue("lsbitfirst", false);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -73,7 +73,7 @@ FfmpegOpenInput(AVIOContext *pb,
|
||||
}
|
||||
|
||||
static bool
|
||||
ffmpeg_init(gcc_unused const config_param ¶m)
|
||||
ffmpeg_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
FfmpegInit();
|
||||
return true;
|
||||
|
@ -291,7 +291,7 @@ flac_decode(Decoder &decoder, InputStream &input_stream)
|
||||
}
|
||||
|
||||
static bool
|
||||
oggflac_init(gcc_unused const config_param ¶m)
|
||||
oggflac_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
return !!FLAC_API_SUPPORTS_OGG_FLAC;
|
||||
}
|
||||
|
@ -73,17 +73,17 @@ fluidsynth_mpd_log_function(int level, char *message, gcc_unused void *data)
|
||||
}
|
||||
|
||||
static bool
|
||||
fluidsynth_init(const config_param ¶m)
|
||||
fluidsynth_init(const ConfigBlock &block)
|
||||
{
|
||||
Error error;
|
||||
|
||||
sample_rate = param.GetBlockValue("sample_rate", 48000u);
|
||||
sample_rate = block.GetBlockValue("sample_rate", 48000u);
|
||||
if (!audio_check_sample_rate(sample_rate, error)) {
|
||||
LogError(error);
|
||||
return false;
|
||||
}
|
||||
|
||||
soundfont_path = param.GetBlockValue("soundfont",
|
||||
soundfont_path = block.GetBlockValue("soundfont",
|
||||
"/usr/share/sounds/sf2/FluidR3_GM.sf2");
|
||||
|
||||
fluid_set_log_function(LAST_LOG_LEVEL,
|
||||
|
@ -107,7 +107,7 @@ mad_fixed_to_24_buffer(int32_t *dest, const struct mad_synth *synth,
|
||||
}
|
||||
|
||||
static bool
|
||||
mp3_plugin_init(gcc_unused const config_param ¶m)
|
||||
mp3_plugin_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
gapless_playback = config_get_bool(ConfigOption::GAPLESS_MP3_PLAYBACK,
|
||||
DEFAULT_GAPLESS_MP3_PLAYBACK);
|
||||
|
@ -109,15 +109,15 @@ static bool mikmod_loop;
|
||||
static unsigned mikmod_sample_rate;
|
||||
|
||||
static bool
|
||||
mikmod_decoder_init(const config_param ¶m)
|
||||
mikmod_decoder_init(const ConfigBlock &block)
|
||||
{
|
||||
static char params[] = "";
|
||||
|
||||
mikmod_loop = param.GetBlockValue("loop", false);
|
||||
mikmod_sample_rate = param.GetBlockValue("sample_rate", 44100u);
|
||||
mikmod_loop = block.GetBlockValue("loop", false);
|
||||
mikmod_sample_rate = block.GetBlockValue("sample_rate", 44100u);
|
||||
if (!audio_valid_sample_rate(mikmod_sample_rate))
|
||||
FormatFatalError("Invalid sample rate in line %d: %u",
|
||||
param.line, mikmod_sample_rate);
|
||||
block.line, mikmod_sample_rate);
|
||||
|
||||
md_device = 0;
|
||||
md_reverb = 0;
|
||||
|
@ -41,12 +41,12 @@ static constexpr offset_type MODPLUG_FILE_LIMIT = 100 * 1024 * 1024;
|
||||
static int modplug_loop_count;
|
||||
|
||||
static bool
|
||||
modplug_decoder_init(const config_param ¶m)
|
||||
modplug_decoder_init(const ConfigBlock &block)
|
||||
{
|
||||
modplug_loop_count = param.GetBlockValue("loop_count", 0);
|
||||
modplug_loop_count = block.GetBlockValue("loop_count", 0);
|
||||
if (modplug_loop_count < -1)
|
||||
FormatFatalError("Invalid loop count in line %d: %i",
|
||||
param.line, modplug_loop_count);
|
||||
block.line, modplug_loop_count);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
static constexpr Domain mpg123_domain("mpg123");
|
||||
|
||||
static bool
|
||||
mpd_mpg123_init(gcc_unused const config_param ¶m)
|
||||
mpd_mpg123_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
mpg123_init();
|
||||
|
||||
|
@ -61,7 +61,7 @@ IsOpusTags(const ogg_packet &packet)
|
||||
}
|
||||
|
||||
static bool
|
||||
mpd_opus_init(gcc_unused const config_param ¶m)
|
||||
mpd_opus_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
LogDebug(opus_domain, opus_get_version_string());
|
||||
|
||||
|
@ -64,22 +64,22 @@ sidplay_load_songlength_db(const Path path)
|
||||
}
|
||||
|
||||
static bool
|
||||
sidplay_init(const config_param ¶m)
|
||||
sidplay_init(const ConfigBlock &block)
|
||||
{
|
||||
/* read the songlengths database file */
|
||||
Error error;
|
||||
const auto database_path = param.GetBlockPath("songlength_database", error);
|
||||
const auto database_path = block.GetBlockPath("songlength_database", error);
|
||||
if (!database_path.IsNull())
|
||||
songlength_database = sidplay_load_songlength_db(database_path);
|
||||
else if (error.IsDefined())
|
||||
FatalError(error);
|
||||
|
||||
default_songlength = param.GetBlockValue("default_songlength", 0u);
|
||||
default_songlength = block.GetBlockValue("default_songlength", 0u);
|
||||
|
||||
all_files_are_containers =
|
||||
param.GetBlockValue("all_files_are_containers", true);
|
||||
block.GetBlockValue("all_files_are_containers", true);
|
||||
|
||||
filter_setting = param.GetBlockValue("filter", true);
|
||||
filter_setting = block.GetBlockValue("filter", true);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -32,7 +32,7 @@
|
||||
static constexpr Domain sndfile_domain("sndfile");
|
||||
|
||||
static bool
|
||||
sndfile_init(gcc_unused const config_param ¶m)
|
||||
sndfile_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
LogDebug(sndfile_domain, sf_version_string());
|
||||
return true;
|
||||
|
@ -194,7 +194,7 @@ vorbis_interleave(float *dest, const float *const*src,
|
||||
/* public */
|
||||
|
||||
static bool
|
||||
vorbis_init(gcc_unused const config_param ¶m)
|
||||
vorbis_init(gcc_unused const ConfigBlock &block)
|
||||
{
|
||||
#ifndef HAVE_TREMOR
|
||||
LogDebug(vorbis_domain, vorbis_version_string());
|
||||
|
@ -38,11 +38,11 @@ static constexpr Domain wildmidi_domain("wildmidi");
|
||||
static constexpr unsigned WILDMIDI_SAMPLE_RATE = 48000;
|
||||
|
||||
static bool
|
||||
wildmidi_init(const config_param ¶m)
|
||||
wildmidi_init(const ConfigBlock &block)
|
||||
{
|
||||
Error error;
|
||||
const AllocatedPath path =
|
||||
param.GetBlockPath("config_file",
|
||||
block.GetBlockPath("config_file",
|
||||
"/etc/timidity/timidity.cfg",
|
||||
error);
|
||||
if (path.IsNull())
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "EncoderPlugin.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
|
@ -24,14 +24,14 @@
|
||||
|
||||
struct Encoder;
|
||||
struct AudioFormat;
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
struct Tag;
|
||||
class Error;
|
||||
|
||||
struct EncoderPlugin {
|
||||
const char *name;
|
||||
|
||||
Encoder *(*init)(const config_param ¶m,
|
||||
Encoder *(*init)(const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
void (*finish)(Encoder *encoder);
|
||||
@ -69,10 +69,10 @@ struct EncoderPlugin {
|
||||
* @return an encoder object on success, nullptr on failure
|
||||
*/
|
||||
static inline Encoder *
|
||||
encoder_init(const EncoderPlugin &plugin, const config_param ¶m,
|
||||
encoder_init(const EncoderPlugin &plugin, const ConfigBlock &block,
|
||||
Error &error_r)
|
||||
{
|
||||
return plugin.init(param, error_r);
|
||||
return plugin.init(block, error_r);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -56,21 +56,21 @@ struct flac_encoder {
|
||||
static constexpr Domain flac_encoder_domain("vorbis_encoder");
|
||||
|
||||
static bool
|
||||
flac_encoder_configure(struct flac_encoder *encoder, const config_param ¶m,
|
||||
flac_encoder_configure(struct flac_encoder *encoder, const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
encoder->compression = param.GetBlockValue("compression", 5u);
|
||||
encoder->compression = block.GetBlockValue("compression", 5u);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
flac_encoder_init(const config_param ¶m, Error &error)
|
||||
flac_encoder_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
flac_encoder *encoder = new flac_encoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!flac_encoder_configure(encoder, param, error)) {
|
||||
/* load configuration from "block" */
|
||||
if (!flac_encoder_configure(encoder, block, error)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -47,18 +47,18 @@ struct LameEncoder final {
|
||||
|
||||
LameEncoder():encoder(lame_encoder_plugin) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
};
|
||||
|
||||
static constexpr Domain lame_encoder_domain("lame_encoder");
|
||||
|
||||
bool
|
||||
LameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
LameEncoder::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value;
|
||||
char *endptr;
|
||||
|
||||
value = param.GetBlockValue("quality");
|
||||
value = block.GetBlockValue("quality");
|
||||
if (value != nullptr) {
|
||||
/* a quality was configured (VBR) */
|
||||
|
||||
@ -72,7 +72,7 @@ LameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param.GetBlockValue("bitrate") != nullptr) {
|
||||
if (block.GetBlockValue("bitrate") != nullptr) {
|
||||
error.Set(config_domain,
|
||||
"quality and bitrate are both defined");
|
||||
return false;
|
||||
@ -80,7 +80,7 @@ LameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
} else {
|
||||
/* a bit rate was configured */
|
||||
|
||||
value = param.GetBlockValue("bitrate");
|
||||
value = block.GetBlockValue("bitrate");
|
||||
if (value == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"neither bitrate nor quality defined");
|
||||
@ -101,12 +101,12 @@ LameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
lame_encoder_init(const config_param ¶m, Error &error)
|
||||
lame_encoder_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
LameEncoder *encoder = new LameEncoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!encoder->Configure(param, error)) {
|
||||
/* load configuration from "block" */
|
||||
if (!encoder->Configure(block, error)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -36,7 +36,7 @@ struct NullEncoder final {
|
||||
};
|
||||
|
||||
static Encoder *
|
||||
null_encoder_init(gcc_unused const config_param ¶m,
|
||||
null_encoder_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
NullEncoder *encoder = new NullEncoder();
|
||||
|
@ -73,9 +73,9 @@ static constexpr Domain opus_encoder_domain("opus_encoder");
|
||||
|
||||
static bool
|
||||
opus_encoder_configure(struct opus_encoder *encoder,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value = param.GetBlockValue("bitrate", "auto");
|
||||
const char *value = block.GetBlockValue("bitrate", "auto");
|
||||
if (strcmp(value, "auto") == 0)
|
||||
encoder->bitrate = OPUS_AUTO;
|
||||
else if (strcmp(value, "max") == 0)
|
||||
@ -90,13 +90,13 @@ opus_encoder_configure(struct opus_encoder *encoder,
|
||||
}
|
||||
}
|
||||
|
||||
encoder->complexity = param.GetBlockValue("complexity", 10u);
|
||||
encoder->complexity = block.GetBlockValue("complexity", 10u);
|
||||
if (encoder->complexity > 10) {
|
||||
error.Format(config_domain, "Invalid complexity");
|
||||
return false;
|
||||
}
|
||||
|
||||
value = param.GetBlockValue("signal", "auto");
|
||||
value = block.GetBlockValue("signal", "auto");
|
||||
if (strcmp(value, "auto") == 0)
|
||||
encoder->signal = OPUS_AUTO;
|
||||
else if (strcmp(value, "voice") == 0)
|
||||
@ -112,12 +112,12 @@ opus_encoder_configure(struct opus_encoder *encoder,
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
opus_encoder_init(const config_param ¶m, Error &error)
|
||||
opus_encoder_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
opus_encoder *encoder = new opus_encoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!opus_encoder_configure(encoder, param, error)) {
|
||||
/* load configuration from "block" */
|
||||
if (!opus_encoder_configure(encoder, block, error)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -53,7 +53,7 @@ struct ShineEncoder {
|
||||
|
||||
ShineEncoder():encoder(shine_encoder_plugin){}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Setup(Error &error);
|
||||
|
||||
@ -63,22 +63,21 @@ struct ShineEncoder {
|
||||
static constexpr Domain shine_encoder_domain("shine_encoder");
|
||||
|
||||
inline bool
|
||||
ShineEncoder::Configure(const config_param ¶m,
|
||||
gcc_unused Error &error)
|
||||
ShineEncoder::Configure(const ConfigBlock &block, gcc_unused Error &error)
|
||||
{
|
||||
shine_set_config_mpeg_defaults(&config.mpeg);
|
||||
config.mpeg.bitr = param.GetBlockValue("bitrate", 128);
|
||||
config.mpeg.bitr = block.GetBlockValue("bitrate", 128);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
shine_encoder_init(const config_param ¶m, Error &error)
|
||||
shine_encoder_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
ShineEncoder *encoder = new ShineEncoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!encoder->Configure(param, error)) {
|
||||
/* load configuration from "block" */
|
||||
if (!encoder->Configure(block, error)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -53,18 +53,18 @@ struct TwolameEncoder final {
|
||||
|
||||
TwolameEncoder():encoder(twolame_encoder_plugin) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
};
|
||||
|
||||
static constexpr Domain twolame_encoder_domain("twolame_encoder");
|
||||
|
||||
bool
|
||||
TwolameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
TwolameEncoder::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value;
|
||||
char *endptr;
|
||||
|
||||
value = param.GetBlockValue("quality");
|
||||
value = block.GetBlockValue("quality");
|
||||
if (value != nullptr) {
|
||||
/* a quality was configured (VBR) */
|
||||
|
||||
@ -78,7 +78,7 @@ TwolameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param.GetBlockValue("bitrate") != nullptr) {
|
||||
if (block.GetBlockValue("bitrate") != nullptr) {
|
||||
error.Set(config_domain,
|
||||
"quality and bitrate are both defined");
|
||||
return false;
|
||||
@ -86,7 +86,7 @@ TwolameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
} else {
|
||||
/* a bit rate was configured */
|
||||
|
||||
value = param.GetBlockValue("bitrate");
|
||||
value = block.GetBlockValue("bitrate");
|
||||
if (value == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"neither bitrate nor quality defined");
|
||||
@ -107,15 +107,15 @@ TwolameEncoder::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
twolame_encoder_init(const config_param ¶m, Error &error_r)
|
||||
twolame_encoder_init(const ConfigBlock &block, Error &error_r)
|
||||
{
|
||||
FormatDebug(twolame_encoder_domain,
|
||||
"libtwolame version %s", get_twolame_version());
|
||||
|
||||
TwolameEncoder *encoder = new TwolameEncoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!encoder->Configure(param, error_r)) {
|
||||
/* load configuration from "block" */
|
||||
if (!encoder->Configure(block, error_r)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -58,9 +58,9 @@ static constexpr Domain vorbis_encoder_domain("vorbis_encoder");
|
||||
|
||||
static bool
|
||||
vorbis_encoder_configure(struct vorbis_encoder &encoder,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value = param.GetBlockValue("quality");
|
||||
const char *value = block.GetBlockValue("quality");
|
||||
if (value != nullptr) {
|
||||
/* a quality was configured (VBR) */
|
||||
|
||||
@ -76,7 +76,7 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param.GetBlockValue("bitrate") != nullptr) {
|
||||
if (block.GetBlockValue("bitrate") != nullptr) {
|
||||
error.Set(config_domain,
|
||||
"quality and bitrate are both defined");
|
||||
return false;
|
||||
@ -84,7 +84,7 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
|
||||
} else {
|
||||
/* a bit rate was configured */
|
||||
|
||||
value = param.GetBlockValue("bitrate");
|
||||
value = block.GetBlockValue("bitrate");
|
||||
if (value == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"neither bitrate nor quality defined");
|
||||
@ -106,12 +106,12 @@ vorbis_encoder_configure(struct vorbis_encoder &encoder,
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
vorbis_encoder_init(const config_param ¶m, Error &error)
|
||||
vorbis_encoder_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
vorbis_encoder *encoder = new vorbis_encoder();
|
||||
|
||||
/* load configuration from "param" */
|
||||
if (!vorbis_encoder_configure(*encoder, param, error)) {
|
||||
/* load configuration from "block" */
|
||||
if (!vorbis_encoder_configure(*encoder, block, error)) {
|
||||
/* configuration has failed, roll back and return error */
|
||||
delete encoder;
|
||||
return nullptr;
|
||||
|
@ -79,7 +79,7 @@ fill_wave_header(struct wave_header *header, int channels, int bits,
|
||||
}
|
||||
|
||||
static Encoder *
|
||||
wave_encoder_init(gcc_unused const config_param ¶m,
|
||||
wave_encoder_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
WaveEncoder *encoder = new WaveEncoder();
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "config/ConfigOption.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <algorithm>
|
||||
@ -34,9 +35,8 @@
|
||||
static bool
|
||||
filter_chain_append_new(Filter &chain, const char *template_name, Error &error)
|
||||
{
|
||||
const struct config_param *cfg =
|
||||
config_find_block(ConfigOption::AUDIO_FILTER, "name",
|
||||
template_name);
|
||||
const auto *cfg = config_find_block(ConfigBlockOption::AUDIO_FILTER,
|
||||
"name", template_name);
|
||||
if (cfg == nullptr) {
|
||||
error.Format(config_domain,
|
||||
"filter template not found: %s",
|
||||
|
@ -20,7 +20,7 @@
|
||||
#include "config.h"
|
||||
#include "FilterPlugin.hxx"
|
||||
#include "FilterRegistry.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
@ -28,20 +28,20 @@
|
||||
|
||||
Filter *
|
||||
filter_new(const struct filter_plugin *plugin,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
assert(plugin != nullptr);
|
||||
assert(!error.IsDefined());
|
||||
|
||||
return plugin->init(param, error);
|
||||
return plugin->init(block, error);
|
||||
}
|
||||
|
||||
Filter *
|
||||
filter_configured_new(const config_param ¶m, Error &error)
|
||||
filter_configured_new(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
assert(!error.IsDefined());
|
||||
|
||||
const char *plugin_name = param.GetBlockValue("plugin");
|
||||
const char *plugin_name = block.GetBlockValue("plugin");
|
||||
if (plugin_name == nullptr) {
|
||||
error.Set(config_domain, "No filter plugin specified");
|
||||
return nullptr;
|
||||
@ -54,5 +54,5 @@ filter_configured_new(const config_param ¶m, Error &error)
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return filter_new(plugin, param, error);
|
||||
return filter_new(plugin, block, error);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#ifndef MPD_FILTER_PLUGIN_HXX
|
||||
#define MPD_FILTER_PLUGIN_HXX
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class Filter;
|
||||
class Error;
|
||||
|
||||
@ -36,7 +36,7 @@ struct filter_plugin {
|
||||
/**
|
||||
* Allocates and configures a filter.
|
||||
*/
|
||||
Filter *(*init)(const config_param ¶m, Error &error);
|
||||
Filter *(*init)(const ConfigBlock &block, Error &error);
|
||||
};
|
||||
|
||||
/**
|
||||
@ -50,7 +50,7 @@ struct filter_plugin {
|
||||
*/
|
||||
Filter *
|
||||
filter_new(const struct filter_plugin *plugin,
|
||||
const config_param ¶m, Error &error);
|
||||
const ConfigBlock &block, Error &error);
|
||||
|
||||
/**
|
||||
* Creates a new filter, loads configuration and the plugin name from
|
||||
@ -62,6 +62,6 @@ filter_new(const struct filter_plugin *plugin,
|
||||
* @return a new filter object, or nullptr on error
|
||||
*/
|
||||
Filter *
|
||||
filter_configured_new(const config_param ¶m, Error &error);
|
||||
filter_configured_new(const ConfigBlock &block, Error &error);
|
||||
|
||||
#endif
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "filter/FilterInternal.hxx"
|
||||
#include "filter/FilterRegistry.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "util/ConstBuffer.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
@ -70,7 +70,7 @@ AutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error)
|
||||
if (in_audio_format != child_audio_format) {
|
||||
/* yes - create a convert_filter */
|
||||
|
||||
const config_param empty;
|
||||
const ConfigBlock empty;
|
||||
convert = filter_new(&convert_filter_plugin, empty, error);
|
||||
if (convert == nullptr) {
|
||||
filter->Close();
|
||||
|
@ -70,7 +70,7 @@ private:
|
||||
static constexpr Domain chain_filter_domain("chain_filter");
|
||||
|
||||
static Filter *
|
||||
chain_filter_init(gcc_unused const config_param ¶m,
|
||||
chain_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new ChainFilter();
|
||||
|
@ -59,7 +59,7 @@ public:
|
||||
};
|
||||
|
||||
static Filter *
|
||||
convert_filter_init(gcc_unused const config_param ¶m,
|
||||
convert_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new ConvertFilter();
|
||||
|
@ -42,7 +42,7 @@ public:
|
||||
};
|
||||
|
||||
static Filter *
|
||||
normalize_filter_init(gcc_unused const config_param ¶m,
|
||||
normalize_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new NormalizeFilter();
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
};
|
||||
|
||||
static Filter *
|
||||
null_filter_init(gcc_unused const config_param ¶m,
|
||||
null_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new NullFilter();
|
||||
|
@ -150,7 +150,7 @@ ReplayGainFilter::Update()
|
||||
}
|
||||
|
||||
static Filter *
|
||||
replay_gain_filter_init(gcc_unused const config_param ¶m,
|
||||
replay_gain_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new ReplayGainFilter();
|
||||
|
@ -41,7 +41,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "filter/FilterPlugin.hxx"
|
||||
#include "filter/FilterInternal.hxx"
|
||||
@ -114,11 +114,11 @@ public:
|
||||
* a>b, c>d, e>f, ...
|
||||
* where a... are non-unique, non-negative integers
|
||||
* and input channel a gets copied to output channel b, etc.
|
||||
* @param param the configuration block to read
|
||||
* @param block the configuration block to read
|
||||
* @param filter a route_filter whose min_channels and sources[] to set
|
||||
* @return true on success, false on error
|
||||
*/
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
/* virtual methods from class Filter */
|
||||
AudioFormat Open(AudioFormat &af, Error &error) override;
|
||||
@ -128,7 +128,7 @@ public:
|
||||
};
|
||||
|
||||
bool
|
||||
RouteFilter::Configure(const config_param ¶m, Error &error) {
|
||||
RouteFilter::Configure(const ConfigBlock &block, Error &error) {
|
||||
|
||||
/* TODO:
|
||||
* With a more clever way of marking "don't copy to output N",
|
||||
@ -142,7 +142,7 @@ RouteFilter::Configure(const config_param ¶m, Error &error) {
|
||||
min_output_channels = 0;
|
||||
|
||||
// A cowardly default, just passthrough stereo
|
||||
const char *routes = param.GetBlockValue("routes", "0>0, 1>1");
|
||||
const char *routes = block.GetBlockValue("routes", "0>0, 1>1");
|
||||
while (true) {
|
||||
routes = StripLeft(routes);
|
||||
|
||||
@ -205,10 +205,10 @@ RouteFilter::Configure(const config_param ¶m, Error &error) {
|
||||
}
|
||||
|
||||
static Filter *
|
||||
route_filter_init(const config_param ¶m, Error &error)
|
||||
route_filter_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
RouteFilter *filter = new RouteFilter();
|
||||
if (!filter->Configure(param, error)) {
|
||||
if (!filter->Configure(block, error)) {
|
||||
delete filter;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ public:
|
||||
static constexpr Domain volume_domain("pcm_volume");
|
||||
|
||||
static Filter *
|
||||
volume_filter_init(gcc_unused const config_param ¶m,
|
||||
volume_filter_init(gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new VolumeFilter();
|
||||
|
@ -24,7 +24,7 @@
|
||||
#include "util/Error.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/ConfigOption.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
@ -33,7 +33,7 @@
|
||||
bool
|
||||
input_stream_global_init(Error &error)
|
||||
{
|
||||
const config_param empty;
|
||||
const ConfigBlock empty;
|
||||
|
||||
for (unsigned i = 0; input_plugins[i] != nullptr; ++i) {
|
||||
const InputPlugin *plugin = input_plugins[i];
|
||||
@ -42,17 +42,17 @@ input_stream_global_init(Error &error)
|
||||
assert(*plugin->name != 0);
|
||||
assert(plugin->open != nullptr);
|
||||
|
||||
const struct config_param *param =
|
||||
config_find_block(ConfigOption::INPUT, "plugin",
|
||||
const auto *block =
|
||||
config_find_block(ConfigBlockOption::INPUT, "plugin",
|
||||
plugin->name);
|
||||
if (param == nullptr) {
|
||||
param = ∅
|
||||
} else if (!param->GetBlockValue("enabled", true))
|
||||
if (block == nullptr) {
|
||||
block = ∅
|
||||
} else if (!block->GetBlockValue("enabled", true))
|
||||
/* the plugin is disabled in mpd.conf */
|
||||
continue;
|
||||
|
||||
InputPlugin::InitResult result = plugin->init != nullptr
|
||||
? plugin->init(*param, error)
|
||||
? plugin->init(*block, error)
|
||||
: InputPlugin::InitResult::SUCCESS;
|
||||
|
||||
switch (result) {
|
||||
|
@ -34,7 +34,7 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class InputStream;
|
||||
class Error;
|
||||
struct Tag;
|
||||
@ -69,7 +69,7 @@ struct InputPlugin {
|
||||
* @return true on success, false if the plugin should be
|
||||
* disabled
|
||||
*/
|
||||
InitResult (*init)(const config_param ¶m, Error &error);
|
||||
InitResult (*init)(const ConfigBlock &block, Error &error);
|
||||
|
||||
/**
|
||||
* Global deinitialization. Called once before MPD shuts
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include "system/ByteOrder.hxx"
|
||||
#include "fs/AllocatedPath.hxx"
|
||||
#include "Log.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -106,9 +106,9 @@ static constexpr Domain cdio_domain("cdio");
|
||||
static bool default_reverse_endian;
|
||||
|
||||
static InputPlugin::InitResult
|
||||
input_cdio_init(const config_param ¶m, Error &error)
|
||||
input_cdio_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value = param.GetBlockValue("default_byte_order");
|
||||
const char *value = block.GetBlockValue("default_byte_order");
|
||||
if (value != nullptr) {
|
||||
if (strcmp(value, "little_endian") == 0)
|
||||
default_reverse_endian = IsBigEndian();
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "../IcyInputStream.hxx"
|
||||
#include "../InputPlugin.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "tag/TagBuilder.hxx"
|
||||
#include "event/SocketMonitor.hxx"
|
||||
@ -535,7 +535,7 @@ CurlMulti::OnTimeout()
|
||||
*/
|
||||
|
||||
static InputPlugin::InitResult
|
||||
input_curl_init(const config_param ¶m, Error &error)
|
||||
input_curl_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
CURLcode code = curl_global_init(CURL_GLOBAL_ALL);
|
||||
if (code != CURLE_OK) {
|
||||
@ -557,10 +557,10 @@ input_curl_init(const config_param ¶m, Error &error)
|
||||
|
||||
http_200_aliases = curl_slist_append(http_200_aliases, "ICY 200 OK");
|
||||
|
||||
proxy = param.GetBlockValue("proxy");
|
||||
proxy_port = param.GetBlockValue("proxy_port", 0u);
|
||||
proxy_user = param.GetBlockValue("proxy_user");
|
||||
proxy_password = param.GetBlockValue("proxy_password");
|
||||
proxy = block.GetBlockValue("proxy");
|
||||
proxy_port = block.GetBlockValue("proxy_port", 0u);
|
||||
proxy_user = block.GetBlockValue("proxy_user");
|
||||
proxy_password = block.GetBlockValue("proxy_password");
|
||||
|
||||
if (proxy == nullptr) {
|
||||
/* deprecated proxy configuration */
|
||||
@ -571,8 +571,8 @@ input_curl_init(const config_param ¶m, Error &error)
|
||||
"");
|
||||
}
|
||||
|
||||
verify_peer = param.GetBlockValue("verify_peer", true);
|
||||
verify_host = param.GetBlockValue("verify_host", true);
|
||||
verify_peer = block.GetBlockValue("verify_peer", true);
|
||||
verify_host = block.GetBlockValue("verify_host", true);
|
||||
|
||||
CURLM *multi = curl_multi_init();
|
||||
if (multi == nullptr) {
|
||||
|
@ -72,7 +72,7 @@ input_ffmpeg_supported(void)
|
||||
}
|
||||
|
||||
static InputPlugin::InitResult
|
||||
input_ffmpeg_init(gcc_unused const config_param ¶m,
|
||||
input_ffmpeg_init(gcc_unused const ConfigBlock &block,
|
||||
Error &error)
|
||||
{
|
||||
FfmpegInit();
|
||||
|
@ -221,7 +221,7 @@ NfsInputStream::OnNfsFileError(Error &&error)
|
||||
*/
|
||||
|
||||
static InputPlugin::InitResult
|
||||
input_nfs_init(const config_param &, Error &)
|
||||
input_nfs_init(const ConfigBlock &, Error &)
|
||||
{
|
||||
nfs_init();
|
||||
return InputPlugin::InitResult::SUCCESS;
|
||||
|
@ -66,14 +66,14 @@ public:
|
||||
*/
|
||||
|
||||
static InputPlugin::InitResult
|
||||
input_smbclient_init(gcc_unused const config_param ¶m, Error &error)
|
||||
input_smbclient_init(gcc_unused const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!SmbclientInit(error))
|
||||
return InputPlugin::InitResult::UNAVAILABLE;
|
||||
|
||||
// TODO: create one global SMBCCTX here?
|
||||
|
||||
// TODO: evaluate config_param, call smbc_setOption*()
|
||||
// TODO: evaluate ConfigBlock, call smbc_setOption*()
|
||||
|
||||
return InputPlugin::InitResult::SUCCESS;
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ Mixer *
|
||||
mixer_new(EventLoop &event_loop,
|
||||
const MixerPlugin &plugin, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error)
|
||||
{
|
||||
Mixer *mixer = plugin.init(event_loop, ao, listener, param, error);
|
||||
Mixer *mixer = plugin.init(event_loop, ao, listener, block, error);
|
||||
|
||||
assert(mixer == nullptr || mixer->IsPlugin(plugin));
|
||||
|
||||
|
@ -31,12 +31,12 @@ class EventLoop;
|
||||
struct AudioOutput;
|
||||
struct MixerPlugin;
|
||||
class MixerListener;
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
|
||||
Mixer *
|
||||
mixer_new(EventLoop &event_loop, const MixerPlugin &plugin, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
void
|
||||
|
@ -27,7 +27,7 @@
|
||||
#ifndef MPD_MIXER_PLUGIN_HXX
|
||||
#define MPD_MIXER_PLUGIN_HXX
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
struct AudioOutput;
|
||||
class Mixer;
|
||||
class MixerListener;
|
||||
@ -46,7 +46,7 @@ struct MixerPlugin {
|
||||
*/
|
||||
Mixer *(*init)(EventLoop &event_loop, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
/**
|
||||
|
@ -82,7 +82,7 @@ public:
|
||||
|
||||
virtual ~AlsaMixer();
|
||||
|
||||
void Configure(const config_param ¶m);
|
||||
void Configure(const ConfigBlock &block);
|
||||
bool Setup(Error &error);
|
||||
|
||||
/* virtual methods from class Mixer */
|
||||
@ -162,24 +162,24 @@ alsa_mixer_elem_callback(snd_mixer_elem_t *elem, unsigned mask)
|
||||
*/
|
||||
|
||||
inline void
|
||||
AlsaMixer::Configure(const config_param ¶m)
|
||||
AlsaMixer::Configure(const ConfigBlock &block)
|
||||
{
|
||||
device = param.GetBlockValue("mixer_device",
|
||||
device = block.GetBlockValue("mixer_device",
|
||||
VOLUME_MIXER_ALSA_DEFAULT);
|
||||
control = param.GetBlockValue("mixer_control",
|
||||
control = block.GetBlockValue("mixer_control",
|
||||
VOLUME_MIXER_ALSA_CONTROL_DEFAULT);
|
||||
index = param.GetBlockValue("mixer_index",
|
||||
index = block.GetBlockValue("mixer_index",
|
||||
VOLUME_MIXER_ALSA_INDEX_DEFAULT);
|
||||
}
|
||||
|
||||
static Mixer *
|
||||
alsa_mixer_init(EventLoop &event_loop, gcc_unused AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
AlsaMixer *am = new AlsaMixer(event_loop, listener);
|
||||
am->Configure(param);
|
||||
am->Configure(block);
|
||||
|
||||
return am;
|
||||
}
|
||||
|
@ -55,7 +55,7 @@ static Mixer *
|
||||
null_mixer_init(gcc_unused EventLoop &event_loop,
|
||||
gcc_unused AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new NullMixer(listener);
|
||||
|
@ -19,7 +19,7 @@
|
||||
|
||||
#include "config.h"
|
||||
#include "mixer/MixerInternal.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "system/fd_util.h"
|
||||
#include "util/ASCII.hxx"
|
||||
#include "util/Error.hxx"
|
||||
@ -52,7 +52,7 @@ public:
|
||||
OssMixer(MixerListener &_listener)
|
||||
:Mixer(oss_mixer_plugin, _listener) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
/* virtual methods from class Mixer */
|
||||
virtual bool Open(Error &error) override;
|
||||
@ -79,10 +79,10 @@ oss_find_mixer(const char *name)
|
||||
}
|
||||
|
||||
inline bool
|
||||
OssMixer::Configure(const config_param ¶m, Error &error)
|
||||
OssMixer::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
device = param.GetBlockValue("mixer_device", VOLUME_MIXER_OSS_DEFAULT);
|
||||
control = param.GetBlockValue("mixer_control");
|
||||
device = block.GetBlockValue("mixer_device", VOLUME_MIXER_OSS_DEFAULT);
|
||||
control = block.GetBlockValue("mixer_control");
|
||||
|
||||
if (control != NULL) {
|
||||
volume_control = oss_find_mixer(control);
|
||||
@ -100,12 +100,12 @@ OssMixer::Configure(const config_param ¶m, Error &error)
|
||||
static Mixer *
|
||||
oss_mixer_init(gcc_unused EventLoop &event_loop, gcc_unused AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error)
|
||||
{
|
||||
OssMixer *om = new OssMixer(listener);
|
||||
|
||||
if (!om->Configure(param, error)) {
|
||||
if (!om->Configure(block, error)) {
|
||||
delete om;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -163,7 +163,7 @@ pulse_mixer_on_change(PulseMixer &pm,
|
||||
static Mixer *
|
||||
pulse_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
PulseOutput &po = (PulseOutput &)ao;
|
||||
|
@ -48,7 +48,7 @@ public:
|
||||
static Mixer *
|
||||
roar_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new RoarMixer((RoarOutput &)ao, listener);
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include "filter/FilterInternal.hxx"
|
||||
#include "filter/plugins/VolumeFilterPlugin.hxx"
|
||||
#include "pcm/Volume.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
#include <assert.h>
|
||||
@ -34,7 +34,7 @@
|
||||
static Filter *
|
||||
CreateVolumeFilter()
|
||||
{
|
||||
return filter_new(&volume_filter_plugin, config_param(),
|
||||
return filter_new(&volume_filter_plugin, ConfigBlock(),
|
||||
IgnoreError());
|
||||
}
|
||||
|
||||
@ -90,7 +90,7 @@ static Mixer *
|
||||
software_mixer_init(gcc_unused EventLoop &event_loop,
|
||||
gcc_unused AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new SoftwareMixer(listener);
|
||||
|
@ -69,7 +69,7 @@ winmm_volume_encode(int volume)
|
||||
static Mixer *
|
||||
winmm_mixer_init(gcc_unused EventLoop &event_loop, AudioOutput &ao,
|
||||
MixerListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new WinmmMixer((WinmmOutput &)ao, listener);
|
||||
|
@ -24,8 +24,8 @@
|
||||
#include "NeighborPlugin.hxx"
|
||||
#include "Info.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "util/Error.hxx"
|
||||
|
||||
NeighborGlue::Explorer::~Explorer()
|
||||
@ -37,9 +37,9 @@ NeighborGlue::~NeighborGlue() {}
|
||||
|
||||
static NeighborExplorer *
|
||||
CreateNeighborExplorer(EventLoop &loop, NeighborListener &listener,
|
||||
const config_param ¶m, Error &error)
|
||||
const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *plugin_name = param.GetBlockValue("plugin");
|
||||
const char *plugin_name = block.GetBlockValue("plugin");
|
||||
if (plugin_name == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"Missing \"plugin\" configuration");
|
||||
@ -53,18 +53,18 @@ CreateNeighborExplorer(EventLoop &loop, NeighborListener &listener,
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return plugin->create(loop, listener, param, error);
|
||||
return plugin->create(loop, listener, block, error);
|
||||
}
|
||||
|
||||
bool
|
||||
NeighborGlue::Init(EventLoop &loop, NeighborListener &listener, Error &error)
|
||||
{
|
||||
for (const auto *param = config_get_param(ConfigOption::NEIGHBORS);
|
||||
param != nullptr; param = param->next) {
|
||||
for (const auto *block = config_get_block(ConfigBlockOption::NEIGHBORS);
|
||||
block != nullptr; block = block->next) {
|
||||
NeighborExplorer *explorer =
|
||||
CreateNeighborExplorer(loop, listener, *param, error);
|
||||
CreateNeighborExplorer(loop, listener, *block, error);
|
||||
if (explorer == nullptr) {
|
||||
error.FormatPrefix("Line %i: ", param->line);
|
||||
error.FormatPrefix("Line %i: ", block->line);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@
|
||||
#ifndef MPD_NEIGHBOR_PLUGIN_HXX
|
||||
#define MPD_NEIGHBOR_PLUGIN_HXX
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
class Error;
|
||||
class EventLoop;
|
||||
class NeighborListener;
|
||||
@ -33,7 +33,7 @@ struct NeighborPlugin {
|
||||
* Allocates and configures a #NeighborExplorer instance.
|
||||
*/
|
||||
NeighborExplorer *(*create)(EventLoop &loop, NeighborListener &listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
};
|
||||
|
||||
|
@ -273,7 +273,7 @@ SmbclientNeighborExplorer::ThreadFunc(void *ctx)
|
||||
static NeighborExplorer *
|
||||
smbclient_neighbor_create(gcc_unused EventLoop &loop,
|
||||
NeighborListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
if (!SmbclientInit(error))
|
||||
|
@ -127,7 +127,7 @@ UpnpNeighborExplorer::LostUPnP(const ContentDirectoryService &service)
|
||||
static NeighborExplorer *
|
||||
upnp_neighbor_create(gcc_unused EventLoop &loop,
|
||||
NeighborListener &listener,
|
||||
gcc_unused const config_param ¶m,
|
||||
gcc_unused const ConfigBlock &block,
|
||||
gcc_unused Error &error)
|
||||
{
|
||||
return new UpnpNeighborExplorer(listener);
|
||||
|
@ -35,6 +35,7 @@
|
||||
#include "filter/plugins/ChainFilterPlugin.hxx"
|
||||
#include "config/ConfigError.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "Log.hxx"
|
||||
|
||||
@ -95,15 +96,15 @@ audio_output_detect(Error &error)
|
||||
*/
|
||||
gcc_pure
|
||||
static MixerType
|
||||
audio_output_mixer_type(const config_param ¶m)
|
||||
audio_output_mixer_type(const ConfigBlock &block)
|
||||
{
|
||||
/* read the local "mixer_type" setting */
|
||||
const char *p = param.GetBlockValue("mixer_type");
|
||||
const char *p = block.GetBlockValue("mixer_type");
|
||||
if (p != nullptr)
|
||||
return mixer_type_parse(p);
|
||||
|
||||
/* try the local "mixer_enabled" setting next (deprecated) */
|
||||
if (!param.GetBlockValue("mixer_enabled", true))
|
||||
if (!block.GetBlockValue("mixer_enabled", true))
|
||||
return MixerType::NONE;
|
||||
|
||||
/* fall back to the global "mixer_type" setting (also
|
||||
@ -114,7 +115,7 @@ audio_output_mixer_type(const config_param ¶m)
|
||||
|
||||
static Mixer *
|
||||
audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
const MixerPlugin *plugin,
|
||||
Filter &filter_chain,
|
||||
MixerListener &listener,
|
||||
@ -122,26 +123,26 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
|
||||
{
|
||||
Mixer *mixer;
|
||||
|
||||
switch (audio_output_mixer_type(param)) {
|
||||
switch (audio_output_mixer_type(block)) {
|
||||
case MixerType::NONE:
|
||||
case MixerType::UNKNOWN:
|
||||
return nullptr;
|
||||
|
||||
case MixerType::NULL_:
|
||||
return mixer_new(event_loop, null_mixer_plugin, ao, listener,
|
||||
param, error);
|
||||
block, error);
|
||||
|
||||
case MixerType::HARDWARE:
|
||||
if (plugin == nullptr)
|
||||
return nullptr;
|
||||
|
||||
return mixer_new(event_loop, *plugin, ao, listener,
|
||||
param, error);
|
||||
block, error);
|
||||
|
||||
case MixerType::SOFTWARE:
|
||||
mixer = mixer_new(event_loop, software_mixer_plugin, ao,
|
||||
listener,
|
||||
config_param(),
|
||||
ConfigBlock(),
|
||||
IgnoreError());
|
||||
assert(mixer != nullptr);
|
||||
|
||||
@ -155,17 +156,17 @@ audio_output_load_mixer(EventLoop &event_loop, AudioOutput &ao,
|
||||
}
|
||||
|
||||
bool
|
||||
AudioOutput::Configure(const config_param ¶m, Error &error)
|
||||
AudioOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!param.IsNull()) {
|
||||
name = param.GetBlockValue(AUDIO_OUTPUT_NAME);
|
||||
if (!block.IsNull()) {
|
||||
name = block.GetBlockValue(AUDIO_OUTPUT_NAME);
|
||||
if (name == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"Missing \"name\" configuration");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *p = param.GetBlockValue(AUDIO_OUTPUT_FORMAT);
|
||||
const char *p = block.GetBlockValue(AUDIO_OUTPUT_FORMAT);
|
||||
if (p != nullptr) {
|
||||
bool success =
|
||||
audio_format_parse(config_audio_format,
|
||||
@ -180,9 +181,9 @@ AudioOutput::Configure(const config_param ¶m, Error &error)
|
||||
config_audio_format.Clear();
|
||||
}
|
||||
|
||||
tags = param.GetBlockValue("tags", true);
|
||||
always_on = param.GetBlockValue("always_on", false);
|
||||
enabled = param.GetBlockValue("enabled", true);
|
||||
tags = block.GetBlockValue("tags", true);
|
||||
always_on = block.GetBlockValue("always_on", false);
|
||||
enabled = block.GetBlockValue("enabled", true);
|
||||
|
||||
/* set up the filter chain */
|
||||
|
||||
@ -193,7 +194,7 @@ AudioOutput::Configure(const config_param ¶m, Error &error)
|
||||
|
||||
if (config_get_bool(ConfigOption::VOLUME_NORMALIZATION, false)) {
|
||||
Filter *normalize_filter =
|
||||
filter_new(&normalize_filter_plugin, config_param(),
|
||||
filter_new(&normalize_filter_plugin, ConfigBlock(),
|
||||
IgnoreError());
|
||||
assert(normalize_filter != nullptr);
|
||||
|
||||
@ -203,7 +204,7 @@ AudioOutput::Configure(const config_param ¶m, Error &error)
|
||||
|
||||
Error filter_error;
|
||||
filter_chain_parse(*filter,
|
||||
param.GetBlockValue(AUDIO_FILTERS, ""),
|
||||
block.GetBlockValue(AUDIO_FILTERS, ""),
|
||||
filter_error);
|
||||
|
||||
// It's not really fatal - Part of the filter chain has been set up already
|
||||
@ -221,24 +222,24 @@ AudioOutput::Configure(const config_param ¶m, Error &error)
|
||||
static bool
|
||||
audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
|
||||
MixerListener &mixer_listener,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error)
|
||||
{
|
||||
|
||||
/* create the replay_gain filter */
|
||||
|
||||
const char *replay_gain_handler =
|
||||
param.GetBlockValue("replay_gain_handler", "software");
|
||||
block.GetBlockValue("replay_gain_handler", "software");
|
||||
|
||||
if (strcmp(replay_gain_handler, "none") != 0) {
|
||||
ao.replay_gain_filter = filter_new(&replay_gain_filter_plugin,
|
||||
param, IgnoreError());
|
||||
block, IgnoreError());
|
||||
assert(ao.replay_gain_filter != nullptr);
|
||||
|
||||
ao.replay_gain_serial = 0;
|
||||
|
||||
ao.other_replay_gain_filter = filter_new(&replay_gain_filter_plugin,
|
||||
param,
|
||||
block,
|
||||
IgnoreError());
|
||||
assert(ao.other_replay_gain_filter != nullptr);
|
||||
|
||||
@ -251,7 +252,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
|
||||
/* set up the mixer */
|
||||
|
||||
Error mixer_error;
|
||||
ao.mixer = audio_output_load_mixer(event_loop, ao, param,
|
||||
ao.mixer = audio_output_load_mixer(event_loop, ao, block,
|
||||
ao.plugin.mixer_plugin,
|
||||
*ao.filter,
|
||||
mixer_listener,
|
||||
@ -279,7 +280,7 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
|
||||
|
||||
/* the "convert" filter must be the last one in the chain */
|
||||
|
||||
ao.convert_filter = filter_new(&convert_filter_plugin, config_param(),
|
||||
ao.convert_filter = filter_new(&convert_filter_plugin, ConfigBlock(),
|
||||
IgnoreError());
|
||||
assert(ao.convert_filter != nullptr);
|
||||
|
||||
@ -289,17 +290,17 @@ audio_output_setup(EventLoop &event_loop, AudioOutput &ao,
|
||||
}
|
||||
|
||||
AudioOutput *
|
||||
audio_output_new(EventLoop &event_loop, const config_param ¶m,
|
||||
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
||||
MixerListener &mixer_listener,
|
||||
PlayerControl &pc,
|
||||
Error &error)
|
||||
{
|
||||
const AudioOutputPlugin *plugin;
|
||||
|
||||
if (!param.IsNull()) {
|
||||
if (!block.IsNull()) {
|
||||
const char *p;
|
||||
|
||||
p = param.GetBlockValue(AUDIO_OUTPUT_TYPE);
|
||||
p = block.GetBlockValue(AUDIO_OUTPUT_TYPE);
|
||||
if (p == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"Missing \"type\" configuration");
|
||||
@ -325,12 +326,12 @@ audio_output_new(EventLoop &event_loop, const config_param ¶m,
|
||||
plugin->name);
|
||||
}
|
||||
|
||||
AudioOutput *ao = ao_plugin_init(plugin, param, error);
|
||||
AudioOutput *ao = ao_plugin_init(plugin, block, error);
|
||||
if (ao == nullptr)
|
||||
return nullptr;
|
||||
|
||||
if (!audio_output_setup(event_loop, *ao, mixer_listener,
|
||||
param, error)) {
|
||||
block, error)) {
|
||||
ao_plugin_finish(ao);
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class EventLoop;
|
||||
class Mixer;
|
||||
class MixerListener;
|
||||
struct MusicChunk;
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
struct PlayerControl;
|
||||
struct AudioOutputPlugin;
|
||||
|
||||
@ -272,7 +272,7 @@ struct AudioOutput {
|
||||
AudioOutput(const AudioOutputPlugin &_plugin);
|
||||
~AudioOutput();
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
void StartThread();
|
||||
void StopThread();
|
||||
@ -430,7 +430,7 @@ private:
|
||||
extern struct notify audio_output_client_notify;
|
||||
|
||||
AudioOutput *
|
||||
audio_output_new(EventLoop &event_loop, const config_param ¶m,
|
||||
audio_output_new(EventLoop &event_loop, const ConfigBlock &block,
|
||||
MixerListener &mixer_listener,
|
||||
PlayerControl &pc,
|
||||
Error &error);
|
||||
|
@ -27,7 +27,7 @@
|
||||
#include "MusicChunk.hxx"
|
||||
#include "system/FatalError.hxx"
|
||||
#include "util/Error.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
#include "config/ConfigGlobal.hxx"
|
||||
#include "config/ConfigOption.hxx"
|
||||
#include "notify.hxx"
|
||||
@ -53,16 +53,16 @@ MultipleOutputs::~MultipleOutputs()
|
||||
|
||||
static AudioOutput *
|
||||
LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
|
||||
PlayerControl &pc, const config_param ¶m)
|
||||
PlayerControl &pc, const ConfigBlock &block)
|
||||
{
|
||||
Error error;
|
||||
AudioOutput *output = audio_output_new(event_loop, param,
|
||||
AudioOutput *output = audio_output_new(event_loop, block,
|
||||
mixer_listener,
|
||||
pc, error);
|
||||
if (output == nullptr) {
|
||||
if (param.line > 0)
|
||||
if (block.line > 0)
|
||||
FormatFatalError("line %i: %s",
|
||||
param.line,
|
||||
block.line,
|
||||
error.GetMessage());
|
||||
else
|
||||
FatalError(error);
|
||||
@ -74,7 +74,7 @@ LoadOutput(EventLoop &event_loop, MixerListener &mixer_listener,
|
||||
void
|
||||
MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
|
||||
{
|
||||
for (const auto *param = config_get_param(ConfigOption::AUDIO_OUTPUT);
|
||||
for (const auto *param = config_get_block(ConfigBlockOption::AUDIO_OUTPUT);
|
||||
param != nullptr; param = param->next) {
|
||||
auto output = LoadOutput(event_loop, mixer_listener,
|
||||
pc, *param);
|
||||
@ -87,7 +87,7 @@ MultipleOutputs::Configure(EventLoop &event_loop, PlayerControl &pc)
|
||||
|
||||
if (outputs.empty()) {
|
||||
/* auto-detect device */
|
||||
const config_param empty;
|
||||
const ConfigBlock empty;
|
||||
auto output = LoadOutput(event_loop, mixer_listener,
|
||||
pc, empty);
|
||||
outputs.push_back(output);
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "Internal.hxx"
|
||||
#include "AudioFormat.hxx"
|
||||
#include "tag/Tag.hxx"
|
||||
#include "config/Param.hxx"
|
||||
#include "config/Block.hxx"
|
||||
|
||||
// IWYU pragma: end_exports
|
||||
|
||||
|
@ -23,13 +23,13 @@
|
||||
|
||||
AudioOutput *
|
||||
ao_plugin_init(const AudioOutputPlugin *plugin,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error)
|
||||
{
|
||||
assert(plugin != nullptr);
|
||||
assert(plugin->init != nullptr);
|
||||
|
||||
return plugin->init(param, error);
|
||||
return plugin->init(block, error);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct config_param;
|
||||
struct ConfigBlock;
|
||||
struct AudioFormat;
|
||||
struct Tag;
|
||||
struct AudioOutput;
|
||||
@ -55,8 +55,7 @@ struct AudioOutputPlugin {
|
||||
* @return nullptr on error, or an opaque pointer to the plugin's
|
||||
* data
|
||||
*/
|
||||
AudioOutput *(*init)(const config_param ¶m,
|
||||
Error &error);
|
||||
AudioOutput *(*init)(const ConfigBlock &block, Error &error);
|
||||
|
||||
/**
|
||||
* Free resources allocated by this device.
|
||||
@ -162,7 +161,7 @@ ao_plugin_test_default_device(const AudioOutputPlugin *plugin)
|
||||
gcc_malloc
|
||||
AudioOutput *
|
||||
ao_plugin_init(const AudioOutputPlugin *plugin,
|
||||
const config_param ¶m,
|
||||
const ConfigBlock &block,
|
||||
Error &error);
|
||||
|
||||
void
|
||||
|
@ -22,14 +22,16 @@
|
||||
|
||||
#include "util/Cast.hxx"
|
||||
|
||||
struct ConfigBlock;
|
||||
|
||||
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);
|
||||
static AudioOutput *Init(const ConfigBlock &block, Error &error) {
|
||||
T *t = T::Create(block, error);
|
||||
return t != nullptr
|
||||
? &t->base
|
||||
: nullptr;
|
||||
|
@ -142,8 +142,8 @@ struct AlsaOutput {
|
||||
return device.empty() ? default_device : device.c_str();
|
||||
}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
static AlsaOutput *Create(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
static AlsaOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Enable(Error &error);
|
||||
void Disable();
|
||||
@ -175,35 +175,35 @@ private:
|
||||
static constexpr Domain alsa_output_domain("alsa_output");
|
||||
|
||||
inline bool
|
||||
AlsaOutput::Configure(const config_param ¶m, Error &error)
|
||||
AlsaOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!base.Configure(param, error))
|
||||
if (!base.Configure(block, error))
|
||||
return false;
|
||||
|
||||
device = param.GetBlockValue("device", "");
|
||||
device = block.GetBlockValue("device", "");
|
||||
|
||||
use_mmap = param.GetBlockValue("use_mmap", false);
|
||||
use_mmap = block.GetBlockValue("use_mmap", false);
|
||||
|
||||
dop = param.GetBlockValue("dop", false) ||
|
||||
dop = block.GetBlockValue("dop", false) ||
|
||||
/* legacy name from MPD 0.18 and older: */
|
||||
param.GetBlockValue("dsd_usb", false);
|
||||
block.GetBlockValue("dsd_usb", false);
|
||||
|
||||
buffer_time = param.GetBlockValue("buffer_time",
|
||||
buffer_time = block.GetBlockValue("buffer_time",
|
||||
MPD_ALSA_BUFFER_TIME_US);
|
||||
period_time = param.GetBlockValue("period_time", 0u);
|
||||
period_time = block.GetBlockValue("period_time", 0u);
|
||||
|
||||
#ifdef SND_PCM_NO_AUTO_RESAMPLE
|
||||
if (!param.GetBlockValue("auto_resample", true))
|
||||
if (!block.GetBlockValue("auto_resample", true))
|
||||
mode |= SND_PCM_NO_AUTO_RESAMPLE;
|
||||
#endif
|
||||
|
||||
#ifdef SND_PCM_NO_AUTO_CHANNELS
|
||||
if (!param.GetBlockValue("auto_channels", true))
|
||||
if (!block.GetBlockValue("auto_channels", true))
|
||||
mode |= SND_PCM_NO_AUTO_CHANNELS;
|
||||
#endif
|
||||
|
||||
#ifdef SND_PCM_NO_AUTO_FORMAT
|
||||
if (!param.GetBlockValue("auto_format", true))
|
||||
if (!block.GetBlockValue("auto_format", true))
|
||||
mode |= SND_PCM_NO_AUTO_FORMAT;
|
||||
#endif
|
||||
|
||||
@ -211,11 +211,11 @@ AlsaOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
inline AlsaOutput *
|
||||
AlsaOutput::Create(const config_param ¶m, Error &error)
|
||||
AlsaOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
AlsaOutput *ad = new AlsaOutput();
|
||||
|
||||
if (!ad->Configure(param, error)) {
|
||||
if (!ad->Configure(block, error)) {
|
||||
delete ad;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -46,11 +46,11 @@ struct AoOutput {
|
||||
AoOutput()
|
||||
:base(ao_output_plugin) {}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error) {
|
||||
return base.Configure(param, error);
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
};
|
||||
|
||||
static constexpr Domain ao_output_domain("ao_output");
|
||||
@ -90,20 +90,20 @@ ao_output_error(Error &error_r)
|
||||
}
|
||||
|
||||
inline bool
|
||||
AoOutput::Configure(const config_param ¶m, Error &error)
|
||||
AoOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *value;
|
||||
|
||||
options = nullptr;
|
||||
|
||||
write_size = param.GetBlockValue("write_size", 1024u);
|
||||
write_size = block.GetBlockValue("write_size", 1024u);
|
||||
|
||||
if (ao_output_ref == 0) {
|
||||
ao_initialize();
|
||||
}
|
||||
ao_output_ref++;
|
||||
|
||||
value = param.GetBlockValue("driver", "default");
|
||||
value = block.GetBlockValue("driver", "default");
|
||||
if (0 == strcmp(value, "default"))
|
||||
driver = ao_default_driver_id();
|
||||
else
|
||||
@ -123,9 +123,9 @@ AoOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
FormatDebug(ao_output_domain, "using ao driver \"%s\" for \"%s\"\n",
|
||||
ai->short_name, param.GetBlockValue("name", nullptr));
|
||||
ai->short_name, block.GetBlockValue("name", nullptr));
|
||||
|
||||
value = param.GetBlockValue("options", nullptr);
|
||||
value = block.GetBlockValue("options", nullptr);
|
||||
if (value != nullptr) {
|
||||
for (const auto &i : SplitString(value, ';')) {
|
||||
const DivideString ss(i.c_str(), '=', true);
|
||||
@ -145,16 +145,16 @@ AoOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
ao_output_init(const config_param ¶m, Error &error)
|
||||
ao_output_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
AoOutput *ad = new AoOutput();
|
||||
|
||||
if (!ad->Initialize(param, error)) {
|
||||
if (!ad->Initialize(block, error)) {
|
||||
delete ad;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!ad->Configure(param, error)) {
|
||||
if (!ad->Configure(block, error)) {
|
||||
delete ad;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -51,8 +51,8 @@ struct FifoOutput {
|
||||
path(AllocatedPath::Null()), input(-1), output(-1),
|
||||
created(false) {}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error) {
|
||||
return base.Configure(param, error);
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
bool Create(Error &error);
|
||||
@ -169,11 +169,11 @@ fifo_open(FifoOutput *fd, Error &error)
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
fifo_output_init(const config_param ¶m, Error &error)
|
||||
fifo_output_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
FifoOutput *fd = new FifoOutput();
|
||||
|
||||
fd->path = param.GetBlockPath("path", error);
|
||||
fd->path = block.GetBlockPath("path", error);
|
||||
if (fd->path.IsNull()) {
|
||||
delete fd;
|
||||
|
||||
@ -185,7 +185,7 @@ fifo_output_init(const config_param ¶m, Error &error)
|
||||
|
||||
fd->path_utf8 = fd->path.ToUTF8();
|
||||
|
||||
if (!fd->Initialize(param, error)) {
|
||||
if (!fd->Initialize(block, error)) {
|
||||
delete fd;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -83,7 +83,7 @@ struct JackOutput {
|
||||
JackOutput()
|
||||
:base(jack_output_plugin) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Connect(Error &error);
|
||||
|
||||
@ -376,14 +376,14 @@ parse_port_list(const char *source, std::string dest[], Error &error)
|
||||
}
|
||||
|
||||
bool
|
||||
JackOutput::Configure(const config_param ¶m, Error &error)
|
||||
JackOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!base.Configure(param, error))
|
||||
if (!base.Configure(block, error))
|
||||
return false;
|
||||
|
||||
options = JackNullOption;
|
||||
|
||||
name = param.GetBlockValue("client_name", nullptr);
|
||||
name = block.GetBlockValue("client_name", nullptr);
|
||||
if (name != nullptr)
|
||||
options = jack_options_t(options | JackUseExactName);
|
||||
else
|
||||
@ -391,30 +391,30 @@ JackOutput::Configure(const config_param ¶m, Error &error)
|
||||
care about the JackUseExactName option */
|
||||
name = "Music Player Daemon";
|
||||
|
||||
server_name = param.GetBlockValue("server_name", nullptr);
|
||||
server_name = block.GetBlockValue("server_name", nullptr);
|
||||
if (server_name != nullptr)
|
||||
options = jack_options_t(options | JackServerName);
|
||||
|
||||
if (!param.GetBlockValue("autostart", false))
|
||||
if (!block.GetBlockValue("autostart", false))
|
||||
options = jack_options_t(options | JackNoStartServer);
|
||||
|
||||
/* configure the source ports */
|
||||
|
||||
const char *value = param.GetBlockValue("source_ports", "left,right");
|
||||
const char *value = block.GetBlockValue("source_ports", "left,right");
|
||||
num_source_ports = parse_port_list(value, source_ports, error);
|
||||
if (num_source_ports == 0)
|
||||
return false;
|
||||
|
||||
/* configure the destination ports */
|
||||
|
||||
value = param.GetBlockValue("destination_ports", nullptr);
|
||||
value = block.GetBlockValue("destination_ports", nullptr);
|
||||
if (value == nullptr) {
|
||||
/* compatibility with MPD < 0.16 */
|
||||
value = param.GetBlockValue("ports", nullptr);
|
||||
value = block.GetBlockValue("ports", nullptr);
|
||||
if (value != nullptr)
|
||||
FormatWarning(jack_output_domain,
|
||||
"deprecated option 'ports' in line %d",
|
||||
param.line);
|
||||
block.line);
|
||||
}
|
||||
|
||||
if (value != nullptr) {
|
||||
@ -432,9 +432,9 @@ JackOutput::Configure(const config_param ¶m, Error &error)
|
||||
"number of source ports (%u) mismatches the "
|
||||
"number of destination ports (%u) in line %d",
|
||||
num_source_ports, num_destination_ports,
|
||||
param.line);
|
||||
block.line);
|
||||
|
||||
ringbuffer_size = param.GetBlockValue("ringbuffer_size", 32768u);
|
||||
ringbuffer_size = block.GetBlockValue("ringbuffer_size", 32768u);
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -463,11 +463,11 @@ JackOutput::Disable()
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
mpd_jack_init(const config_param ¶m, Error &error)
|
||||
mpd_jack_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
JackOutput *jd = new JackOutput();
|
||||
|
||||
if (!jd->Configure(param, error)) {
|
||||
if (!jd->Configure(block, error)) {
|
||||
delete jd;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -36,11 +36,11 @@ public:
|
||||
NullOutput()
|
||||
:base(null_output_plugin) {}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error) {
|
||||
return base.Configure(param, error);
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
static NullOutput *Create(const config_param ¶m, Error &error);
|
||||
static NullOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Open(AudioFormat &audio_format, gcc_unused Error &error) {
|
||||
if (sync)
|
||||
@ -78,16 +78,16 @@ public:
|
||||
};
|
||||
|
||||
inline NullOutput *
|
||||
NullOutput::Create(const config_param ¶m, Error &error)
|
||||
NullOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
NullOutput *nd = new NullOutput();
|
||||
|
||||
if (!nd->Initialize(param, error)) {
|
||||
if (!nd->Initialize(block, error)) {
|
||||
delete nd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nd->sync = param.GetBlockValue("sync", true);
|
||||
nd->sync = block.GetBlockValue("sync", true);
|
||||
|
||||
return nd;
|
||||
}
|
||||
|
@ -61,9 +61,9 @@ osx_output_test_default_device(void)
|
||||
}
|
||||
|
||||
static void
|
||||
osx_output_configure(OSXOutput *oo, const config_param ¶m)
|
||||
osx_output_configure(OSXOutput *oo, const ConfigBlock &block)
|
||||
{
|
||||
const char *device = param.GetBlockValue("device");
|
||||
const char *device = block.GetBlockValue("device");
|
||||
|
||||
if (device == nullptr || 0 == strcmp(device, "default")) {
|
||||
oo->component_subtype = kAudioUnitSubType_DefaultOutput;
|
||||
@ -81,15 +81,15 @@ osx_output_configure(OSXOutput *oo, const config_param ¶m)
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
osx_output_init(const config_param ¶m, Error &error)
|
||||
osx_output_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
OSXOutput *oo = new OSXOutput();
|
||||
if (!oo->base.Configure(param, error)) {
|
||||
if (!oo->base.Configure(block, error)) {
|
||||
delete oo;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
osx_output_configure(oo, param);
|
||||
osx_output_configure(oo, block);
|
||||
|
||||
return &oo->base;
|
||||
}
|
||||
|
@ -54,9 +54,9 @@ class OpenALOutput {
|
||||
OpenALOutput()
|
||||
:base(openal_output_plugin) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
static OpenALOutput *Create(const config_param ¶m, Error &error);
|
||||
static OpenALOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Open(AudioFormat &audio_format, Error &error);
|
||||
|
||||
@ -150,12 +150,12 @@ OpenALOutput::SetupContext(Error &error)
|
||||
}
|
||||
|
||||
inline bool
|
||||
OpenALOutput::Configure(const config_param ¶m, Error &error)
|
||||
OpenALOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!base.Configure(param, error))
|
||||
if (!base.Configure(block, error))
|
||||
return false;
|
||||
|
||||
device_name = param.GetBlockValue("device");
|
||||
device_name = block.GetBlockValue("device");
|
||||
if (device_name == nullptr)
|
||||
device_name = alcGetString(nullptr,
|
||||
ALC_DEFAULT_DEVICE_SPECIFIER);
|
||||
@ -164,11 +164,11 @@ OpenALOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
inline OpenALOutput *
|
||||
OpenALOutput::Create(const config_param ¶m, Error &error)
|
||||
OpenALOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
OpenALOutput *oo = new OpenALOutput();
|
||||
|
||||
if (!oo->Configure(param, error)) {
|
||||
if (!oo->Configure(block, error)) {
|
||||
delete oo;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -87,11 +87,11 @@ public:
|
||||
:base(oss_output_plugin),
|
||||
fd(-1), device(_device) {}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error_r) {
|
||||
return base.Configure(param, error_r);
|
||||
bool Initialize(const ConfigBlock &block, Error &error_r) {
|
||||
return base.Configure(block, error_r);
|
||||
}
|
||||
|
||||
static OssOutput *Create(const config_param ¶m, Error &error);
|
||||
static OssOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
#ifdef AFMT_S24_PACKED
|
||||
bool Enable(gcc_unused Error &error) {
|
||||
@ -192,7 +192,7 @@ oss_open_default(Error &error)
|
||||
int err[ARRAY_SIZE(default_devices)];
|
||||
enum oss_stat ret[ARRAY_SIZE(default_devices)];
|
||||
|
||||
const config_param empty;
|
||||
const ConfigBlock empty;
|
||||
for (int i = ARRAY_SIZE(default_devices); --i >= 0; ) {
|
||||
ret[i] = oss_stat_device(default_devices[i], &err[i]);
|
||||
if (ret[i] == OSS_STAT_NO_ERROR) {
|
||||
@ -236,12 +236,12 @@ oss_open_default(Error &error)
|
||||
}
|
||||
|
||||
inline OssOutput *
|
||||
OssOutput::Create(const config_param ¶m, Error &error)
|
||||
OssOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
const char *device = param.GetBlockValue("device");
|
||||
const char *device = block.GetBlockValue("device");
|
||||
if (device != nullptr) {
|
||||
OssOutput *od = new OssOutput();
|
||||
if (!od->Initialize(param, error)) {
|
||||
if (!od->Initialize(block, error)) {
|
||||
delete od;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -40,10 +40,10 @@ class PipeOutput {
|
||||
PipeOutput()
|
||||
:base(pipe_output_plugin) {}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
public:
|
||||
static PipeOutput *Create(const config_param ¶m, Error &error);
|
||||
static PipeOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Open(AudioFormat &audio_format, Error &error);
|
||||
|
||||
@ -58,12 +58,12 @@ public:
|
||||
static constexpr Domain pipe_output_domain("pipe_output");
|
||||
|
||||
inline bool
|
||||
PipeOutput::Configure(const config_param ¶m, Error &error)
|
||||
PipeOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!base.Configure(param, error))
|
||||
if (!base.Configure(block, error))
|
||||
return false;
|
||||
|
||||
cmd = param.GetBlockValue("command", "");
|
||||
cmd = block.GetBlockValue("command", "");
|
||||
if (cmd.empty()) {
|
||||
error.Set(config_domain,
|
||||
"No \"command\" parameter specified");
|
||||
@ -74,11 +74,11 @@ PipeOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
inline PipeOutput *
|
||||
PipeOutput::Create(const config_param ¶m, Error &error)
|
||||
PipeOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
PipeOutput *po = new PipeOutput();
|
||||
|
||||
if (!po->Configure(param, error)) {
|
||||
if (!po->Configure(block, error)) {
|
||||
delete po;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -98,8 +98,8 @@ public:
|
||||
gcc_const
|
||||
static bool TestDefaultDevice();
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
static PulseOutput *Create(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
static PulseOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Enable(Error &error);
|
||||
void Disable();
|
||||
@ -430,26 +430,26 @@ PulseOutput::SetupContext(Error &error)
|
||||
}
|
||||
|
||||
inline bool
|
||||
PulseOutput::Configure(const config_param ¶m, Error &error)
|
||||
PulseOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
if (!base.Configure(param, error))
|
||||
if (!base.Configure(block, error))
|
||||
return false;
|
||||
|
||||
name = param.GetBlockValue("name", "mpd_pulse");
|
||||
server = param.GetBlockValue("server");
|
||||
sink = param.GetBlockValue("sink");
|
||||
name = block.GetBlockValue("name", "mpd_pulse");
|
||||
server = block.GetBlockValue("server");
|
||||
sink = block.GetBlockValue("sink");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
PulseOutput *
|
||||
PulseOutput::Create(const config_param ¶m, Error &error)
|
||||
PulseOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
setenv("PULSE_PROP_media.role", "music", true);
|
||||
setenv("PULSE_PROP_application.icon_name", "mpd", true);
|
||||
|
||||
auto *po = new PulseOutput();
|
||||
if (!po->Configure(param, error)) {
|
||||
if (!po->Configure(block, error)) {
|
||||
delete po;
|
||||
return nullptr;
|
||||
}
|
||||
@ -926,7 +926,7 @@ PulseOutput::Pause()
|
||||
inline bool
|
||||
PulseOutput::TestDefaultDevice()
|
||||
{
|
||||
const config_param empty;
|
||||
const ConfigBlock empty;
|
||||
PulseOutput *po = PulseOutput::Create(empty, IgnoreError());
|
||||
if (po == nullptr)
|
||||
return false;
|
||||
|
@ -81,13 +81,13 @@ class RecorderOutput {
|
||||
encoder->Dispose();
|
||||
}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error_r) {
|
||||
return base.Configure(param, error_r);
|
||||
bool Initialize(const ConfigBlock &block, Error &error_r) {
|
||||
return base.Configure(block, error_r);
|
||||
}
|
||||
|
||||
static RecorderOutput *Create(const config_param ¶m, Error &error);
|
||||
static RecorderOutput *Create(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
|
||||
bool Open(AudioFormat &audio_format, Error &error);
|
||||
void Close();
|
||||
@ -117,12 +117,12 @@ private:
|
||||
};
|
||||
|
||||
inline bool
|
||||
RecorderOutput::Configure(const config_param ¶m, Error &error)
|
||||
RecorderOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
/* read configuration */
|
||||
|
||||
const char *encoder_name =
|
||||
param.GetBlockValue("encoder", "vorbis");
|
||||
block.GetBlockValue("encoder", "vorbis");
|
||||
const auto encoder_plugin = encoder_plugin_get(encoder_name);
|
||||
if (encoder_plugin == nullptr) {
|
||||
error.Format(config_domain,
|
||||
@ -130,11 +130,11 @@ RecorderOutput::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
path = param.GetBlockPath("path", error);
|
||||
path = block.GetBlockPath("path", error);
|
||||
if (error.IsDefined())
|
||||
return false;
|
||||
|
||||
const char *fmt = param.GetBlockValue("format_path", nullptr);
|
||||
const char *fmt = block.GetBlockValue("format_path", nullptr);
|
||||
if (fmt != nullptr)
|
||||
format_path = fmt;
|
||||
|
||||
@ -150,7 +150,7 @@ RecorderOutput::Configure(const config_param ¶m, Error &error)
|
||||
|
||||
/* initialize encoder */
|
||||
|
||||
encoder = encoder_init(*encoder_plugin, param, error);
|
||||
encoder = encoder_init(*encoder_plugin, block, error);
|
||||
if (encoder == nullptr)
|
||||
return false;
|
||||
|
||||
@ -158,16 +158,16 @@ RecorderOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
RecorderOutput *
|
||||
RecorderOutput::Create(const config_param ¶m, Error &error)
|
||||
RecorderOutput::Create(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
RecorderOutput *recorder = new RecorderOutput();
|
||||
|
||||
if (!recorder->Initialize(param, error)) {
|
||||
if (!recorder->Initialize(block, error)) {
|
||||
delete recorder;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!recorder->Configure(param, error)) {
|
||||
if (!recorder->Configure(block, error)) {
|
||||
delete recorder;
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -60,11 +60,11 @@ public:
|
||||
return &base;
|
||||
}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error) {
|
||||
return base.Configure(param, error);
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
void Configure(const config_param ¶m);
|
||||
void Configure(const ConfigBlock &block);
|
||||
|
||||
bool Open(AudioFormat &audio_format, Error &error);
|
||||
void Close();
|
||||
@ -124,28 +124,28 @@ roar_output_set_volume(RoarOutput &roar, unsigned volume)
|
||||
}
|
||||
|
||||
inline void
|
||||
RoarOutput::Configure(const config_param ¶m)
|
||||
RoarOutput::Configure(const ConfigBlock &block)
|
||||
{
|
||||
host = param.GetBlockValue("server", "");
|
||||
name = param.GetBlockValue("name", "MPD");
|
||||
host = block.GetBlockValue("server", "");
|
||||
name = block.GetBlockValue("name", "MPD");
|
||||
|
||||
const char *_role = param.GetBlockValue("role", "music");
|
||||
const char *_role = block.GetBlockValue("role", "music");
|
||||
role = _role != nullptr
|
||||
? roar_str2role(_role)
|
||||
: ROAR_ROLE_MUSIC;
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
roar_init(const config_param ¶m, Error &error)
|
||||
roar_init(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
RoarOutput *self = new RoarOutput();
|
||||
|
||||
if (!self->Initialize(param, error)) {
|
||||
if (!self->Initialize(block, error)) {
|
||||
delete self;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
self->Configure(param);
|
||||
self->Configure(block);
|
||||
return *self;
|
||||
}
|
||||
|
||||
|
@ -68,11 +68,11 @@ struct ShoutOutput final {
|
||||
shout_free(shout_conn);
|
||||
}
|
||||
|
||||
bool Initialize(const config_param ¶m, Error &error) {
|
||||
return base.Configure(param, error);
|
||||
bool Initialize(const ConfigBlock &block, Error &error) {
|
||||
return base.Configure(block, error);
|
||||
}
|
||||
|
||||
bool Configure(const config_param ¶m, Error &error);
|
||||
bool Configure(const ConfigBlock &block, Error &error);
|
||||
};
|
||||
|
||||
static int shout_init_count;
|
||||
@ -92,18 +92,18 @@ shout_encoder_plugin_get(const char *name)
|
||||
|
||||
gcc_pure
|
||||
static const char *
|
||||
require_block_string(const config_param ¶m, const char *name)
|
||||
require_block_string(const ConfigBlock &block, const char *name)
|
||||
{
|
||||
const char *value = param.GetBlockValue(name);
|
||||
const char *value = block.GetBlockValue(name);
|
||||
if (value == nullptr)
|
||||
FormatFatalError("no \"%s\" defined for shout device defined "
|
||||
"at line %d\n", name, param.line);
|
||||
"at line %d\n", name, block.line);
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
inline bool
|
||||
ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
ShoutOutput::Configure(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
|
||||
const AudioFormat audio_format = base.config_audio_format;
|
||||
@ -113,22 +113,22 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *host = require_block_string(param, "host");
|
||||
const char *mount = require_block_string(param, "mount");
|
||||
unsigned port = param.GetBlockValue("port", 0u);
|
||||
const char *host = require_block_string(block, "host");
|
||||
const char *mount = require_block_string(block, "mount");
|
||||
unsigned port = block.GetBlockValue("port", 0u);
|
||||
if (port == 0) {
|
||||
error.Set(config_domain, "shout port must be configured");
|
||||
return false;
|
||||
}
|
||||
|
||||
const char *passwd = require_block_string(param, "password");
|
||||
const char *name = require_block_string(param, "name");
|
||||
const char *passwd = require_block_string(block, "password");
|
||||
const char *name = require_block_string(block, "name");
|
||||
|
||||
bool is_public = param.GetBlockValue("public", false);
|
||||
bool is_public = block.GetBlockValue("public", false);
|
||||
|
||||
const char *user = param.GetBlockValue("user", "source");
|
||||
const char *user = block.GetBlockValue("user", "source");
|
||||
|
||||
const char *value = param.GetBlockValue("quality");
|
||||
const char *value = block.GetBlockValue("quality");
|
||||
if (value != nullptr) {
|
||||
char *test;
|
||||
quality = strtod(value, &test);
|
||||
@ -141,14 +141,14 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (param.GetBlockValue("bitrate") != nullptr) {
|
||||
if (block.GetBlockValue("bitrate") != nullptr) {
|
||||
error.Set(config_domain,
|
||||
"quality and bitrate are "
|
||||
"both defined");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
value = param.GetBlockValue("bitrate");
|
||||
value = block.GetBlockValue("bitrate");
|
||||
if (value == nullptr) {
|
||||
error.Set(config_domain,
|
||||
"neither bitrate nor quality defined");
|
||||
@ -165,7 +165,7 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
}
|
||||
|
||||
const char *encoding = param.GetBlockValue("encoding", "ogg");
|
||||
const char *encoding = block.GetBlockValue("encoding", "ogg");
|
||||
const auto encoder_plugin = shout_encoder_plugin_get(encoding);
|
||||
if (encoder_plugin == nullptr) {
|
||||
error.Format(config_domain,
|
||||
@ -174,7 +174,7 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
return false;
|
||||
}
|
||||
|
||||
encoder = encoder_init(*encoder_plugin, param, error);
|
||||
encoder = encoder_init(*encoder_plugin, block, error);
|
||||
if (encoder == nullptr)
|
||||
return false;
|
||||
|
||||
@ -185,7 +185,7 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
shout_format = SHOUT_FORMAT_OGG;
|
||||
|
||||
unsigned protocol;
|
||||
value = param.GetBlockValue("protocol");
|
||||
value = block.GetBlockValue("protocol");
|
||||
if (value != nullptr) {
|
||||
if (0 == strcmp(value, "shoutcast") &&
|
||||
0 != strcmp(encoding, "mp3")) {
|
||||
@ -226,21 +226,21 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
/* optional paramters */
|
||||
timeout = param.GetBlockValue("timeout", DEFAULT_CONN_TIMEOUT);
|
||||
timeout = block.GetBlockValue("timeout", DEFAULT_CONN_TIMEOUT);
|
||||
|
||||
value = param.GetBlockValue("genre");
|
||||
value = block.GetBlockValue("genre");
|
||||
if (value != nullptr && shout_set_genre(shout_conn, value)) {
|
||||
error.Set(shout_output_domain, shout_get_error(shout_conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
value = param.GetBlockValue("description");
|
||||
value = block.GetBlockValue("description");
|
||||
if (value != nullptr && shout_set_description(shout_conn, value)) {
|
||||
error.Set(shout_output_domain, shout_get_error(shout_conn));
|
||||
return false;
|
||||
}
|
||||
|
||||
value = param.GetBlockValue("url");
|
||||
value = block.GetBlockValue("url");
|
||||
if (value != nullptr && shout_set_url(shout_conn, value)) {
|
||||
error.Set(shout_output_domain, shout_get_error(shout_conn));
|
||||
return false;
|
||||
@ -272,15 +272,15 @@ ShoutOutput::Configure(const config_param ¶m, Error &error)
|
||||
}
|
||||
|
||||
static AudioOutput *
|
||||
my_shout_init_driver(const config_param ¶m, Error &error)
|
||||
my_shout_init_driver(const ConfigBlock &block, Error &error)
|
||||
{
|
||||
ShoutOutput *sd = new ShoutOutput();
|
||||
if (!sd->Initialize(param, error)) {
|
||||
if (!sd->Initialize(block, error)) {
|
||||
delete sd;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if (!sd->Configure(param, error)) {
|
||||
if (!sd->Configure(block, error)) {
|
||||
delete sd;
|
||||
return nullptr;
|
||||
}
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user