diff options
Diffstat (limited to 'src/pcm/ConfiguredResampler.cxx')
-rw-r--r-- | src/pcm/ConfiguredResampler.cxx | 141 |
1 files changed, 114 insertions, 27 deletions
diff --git a/src/pcm/ConfiguredResampler.cxx b/src/pcm/ConfiguredResampler.cxx index f6aec3f95..30cb801c7 100644 --- a/src/pcm/ConfiguredResampler.cxx +++ b/src/pcm/ConfiguredResampler.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2014 The Music Player Daemon Project + * Copyright (C) 2003-2015 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -23,13 +23,15 @@ #include "config/ConfigGlobal.hxx" #include "config/ConfigOption.hxx" #include "config/ConfigError.hxx" +#include "config/Block.hxx" +#include "config/Param.hxx" #include "util/Error.hxx" -#ifdef HAVE_LIBSAMPLERATE +#ifdef ENABLE_LIBSAMPLERATE #include "LibsamplerateResampler.hxx" #endif -#ifdef HAVE_SOXR +#ifdef ENABLE_SOXR #include "SoxrResampler.hxx" #endif @@ -38,45 +40,130 @@ enum class SelectedResampler { FALLBACK, -#ifdef HAVE_LIBSAMPLERATE +#ifdef ENABLE_LIBSAMPLERATE LIBSAMPLERATE, #endif -#ifdef HAVE_SOXR +#ifdef ENABLE_SOXR SOXR, #endif }; static SelectedResampler selected_resampler = SelectedResampler::FALLBACK; -bool -pcm_resampler_global_init(Error &error) +static const ConfigBlock * +MakeResamplerDefaultConfig(ConfigBlock &block) { - const char *converter = - config_get_string(CONF_SAMPLERATE_CONVERTER, ""); + assert(block.IsEmpty()); + +#ifdef ENABLE_LIBSAMPLERATE + block.AddBlockParam("plugin", "libsamplerate"); +#elif defined(ENABLE_SOXR) + block.AddBlockParam("plugin", "soxr"); +#else + block.AddBlockParam("plugin", "internal"); +#endif + return █ +} - if (strcmp(converter, "internal") == 0) - return true; +/** + * Convert the old "samplerate_converter" setting to a new-style + * "resampler" block. + */ +static const ConfigBlock * +MigrateResamplerConfig(const config_param ¶m, ConfigBlock &block) +{ + assert(block.IsEmpty()); -#ifdef HAVE_SOXR - if (memcmp(converter, "soxr", 4) == 0) { - selected_resampler = SelectedResampler::SOXR; - return pcm_resample_soxr_global_init(converter, error); + block.line = param.line; + + const char *converter = param.value.c_str(); + if (*converter == 0 || strcmp(converter, "internal") == 0) { + block.AddBlockParam("plugin", "internal"); + return █ + } + +#ifdef ENABLE_SOXR + if (strcmp(converter, "soxr") == 0) { + block.AddBlockParam("plugin", "soxr"); + return █ } -#endif -#ifdef HAVE_LIBSAMPLERATE - selected_resampler = SelectedResampler::LIBSAMPLERATE; - return pcm_resample_lsr_global_init(converter, error); + if (memcmp(converter, "soxr ", 5) == 0) { + block.AddBlockParam("plugin", "soxr"); + block.AddBlockParam("quality", converter + 5); + return █ + } #endif - if (*converter == 0) - return true; + block.AddBlockParam("plugin", "libsamplerate"); + block.AddBlockParam("type", converter); + return █ +} + +static const ConfigBlock * +MigrateResamplerConfig(const config_param *param, ConfigBlock &buffer) +{ + assert(buffer.IsEmpty()); - error.Format(config_domain, - "The samplerate_converter '%s' is not available", - converter); - return false; + return param == nullptr + ? MakeResamplerDefaultConfig(buffer) + : MigrateResamplerConfig(*param, buffer); +} + +static const ConfigBlock * +GetResamplerConfig(ConfigBlock &buffer, Error &error) +{ + const auto *old_param = + config_get_param(ConfigOption::SAMPLERATE_CONVERTER); + const auto *block = config_get_block(ConfigBlockOption::RESAMPLER); + if (block == nullptr) + return MigrateResamplerConfig(old_param, buffer); + + if (old_param != nullptr) { + error.Format(config_domain, + "Cannot use both 'resampler' (line %d) and 'samplerate_converter' (line %d)", + block->line, old_param->line); + return nullptr; + } + + return block; +} + +bool +pcm_resampler_global_init(Error &error) +{ + ConfigBlock buffer; + const auto *block = GetResamplerConfig(buffer, error); + if (block == nullptr) + return false; + + const char *plugin_name = block->GetBlockValue("plugin"); + if (plugin_name == nullptr) { + error.Format(config_domain, + "'plugin' missing in line %d", block->line); + return false; + } + + if (strcmp(plugin_name, "internal") == 0) { + selected_resampler = SelectedResampler::FALLBACK; + return true; +#ifdef ENABLE_SOXR + } else if (strcmp(plugin_name, "soxr") == 0) { + selected_resampler = SelectedResampler::SOXR; + return pcm_resample_soxr_global_init(*block, error); +#endif +#ifdef ENABLE_LIBSAMPLERATE + } else if (strcmp(plugin_name, "libsamplerate") == 0) { + selected_resampler = SelectedResampler::LIBSAMPLERATE; + return pcm_resample_lsr_global_init(*block, error); +#endif + } else { + error.Format(config_domain, + "No such resampler plugin: %s", + plugin_name); + return false; + } } PcmResampler * @@ -86,12 +173,12 @@ pcm_resampler_create() case SelectedResampler::FALLBACK: return new FallbackPcmResampler(); -#ifdef HAVE_LIBSAMPLERATE +#ifdef ENABLE_LIBSAMPLERATE case SelectedResampler::LIBSAMPLERATE: return new LibsampleratePcmResampler(); #endif -#ifdef HAVE_SOXR +#ifdef ENABLE_SOXR case SelectedResampler::SOXR: return new SoxrPcmResampler(); #endif |