Config: add section "resampler"
This commit is contained in:
parent
52acea7b1f
commit
0d3b26b3aa
|
@ -1951,14 +1951,17 @@ test_run_normalize_LDADD = \
|
||||||
$(GLIB_LIBS)
|
$(GLIB_LIBS)
|
||||||
|
|
||||||
test_run_convert_SOURCES = test/run_convert.cxx \
|
test_run_convert_SOURCES = test/run_convert.cxx \
|
||||||
src/config/ConfigError.cxx \
|
|
||||||
src/Log.cxx src/LogBackend.cxx \
|
src/Log.cxx src/LogBackend.cxx \
|
||||||
src/AudioFormat.cxx \
|
src/AudioFormat.cxx \
|
||||||
src/CheckAudioFormat.cxx \
|
src/CheckAudioFormat.cxx \
|
||||||
src/AudioParser.cxx
|
src/AudioParser.cxx
|
||||||
test_run_convert_LDADD = \
|
test_run_convert_LDADD = \
|
||||||
$(PCM_LIBS) \
|
$(PCM_LIBS) \
|
||||||
|
libconf.a \
|
||||||
|
$(FS_LIBS) \
|
||||||
|
libsystem.a \
|
||||||
libutil.a \
|
libutil.a \
|
||||||
|
$(ICU_LDADD) \
|
||||||
$(GLIB_LIBS)
|
$(GLIB_LIBS)
|
||||||
|
|
||||||
test_run_output_LDADD = $(MPD_LIBS) \
|
test_run_output_LDADD = $(MPD_LIBS) \
|
||||||
|
|
3
NEWS
3
NEWS
|
@ -18,6 +18,9 @@ ver 0.20 (not yet released)
|
||||||
- recorder: allow dynamic file names
|
- recorder: allow dynamic file names
|
||||||
* mixer
|
* mixer
|
||||||
- null: new plugin
|
- null: new plugin
|
||||||
|
* resampler
|
||||||
|
- new block "resampler" in configuration file
|
||||||
|
replacing the old "samplerate_converter" setting
|
||||||
* reset song priority on playback
|
* reset song priority on playback
|
||||||
* write database and state file atomically
|
* write database and state file atomically
|
||||||
* remove dependency on GLib
|
* remove dependency on GLib
|
||||||
|
|
|
@ -325,13 +325,6 @@ input {
|
||||||
# mixer_type "none" # optional
|
# mixer_type "none" # optional
|
||||||
#}
|
#}
|
||||||
#
|
#
|
||||||
# If MPD has been compiled with libsamplerate support, this setting specifies
|
|
||||||
# the sample rate converter to use. Possible values can be found in the
|
|
||||||
# mpd.conf man page or the libsamplerate documentation. By default, this is
|
|
||||||
# setting is disabled.
|
|
||||||
#
|
|
||||||
#samplerate_converter "Fastest Sinc Interpolator"
|
|
||||||
#
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
||||||
|
|
344
doc/user.xml
344
doc/user.xml
|
@ -771,150 +771,9 @@ systemctl start mpd.socket</programlisting>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
Check the <link linkend="resampler_plugins">resampler plugin
|
Check the <link linkend="resampler_plugins">resampler plugin
|
||||||
reference</link> for a list of resamplers.
|
reference</link> for a list of resamplers and how to
|
||||||
|
configure them.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
|
||||||
The setting <varname>samplerate_converter</varname> controls
|
|
||||||
how <application>MPD</application> shall resample music.
|
|
||||||
Possible values:
|
|
||||||
</para>
|
|
||||||
|
|
||||||
<informaltable>
|
|
||||||
<tgroup cols="2">
|
|
||||||
<thead>
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
Value
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Description
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>internal</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
The internal resampler. Low CPU usage, but very
|
|
||||||
poor quality.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>soxr very high</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Use <application>libsoxr</application> with "Very
|
|
||||||
High Quality" setting.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>soxr high</parameter>" or
|
|
||||||
"<parameter>soxr</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Use <application>libsoxr</application> with "High
|
|
||||||
Quality" setting.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>soxr medium</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Use <application>libsoxr</application> with "Medium
|
|
||||||
Quality" setting.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>soxr low</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Use <application>libsoxr</application> with "Low
|
|
||||||
Quality" setting.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>soxr quick</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
Use <application>libsoxr</application> with "Quick"
|
|
||||||
setting.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>Best Sinc Interpolator</parameter>" or
|
|
||||||
"<parameter>0</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<application>libsamplerate</application>: Band
|
|
||||||
limited sinc interpolation, best quality, 97dB SNR,
|
|
||||||
96% BW.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>Medium Sinc Interpolator</parameter>" or
|
|
||||||
"<parameter>1</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<application>libsamplerate</application>: Band
|
|
||||||
limited sinc interpolation, medium quality, 97dB
|
|
||||||
SNR, 90% BW.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>Fastest Sinc Interpolator</parameter>" or
|
|
||||||
"<parameter>2</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<application>libsamplerate</application>: Band
|
|
||||||
limited sinc interpolation, fastest, 97dB SNR, 80%
|
|
||||||
BW.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>ZOH Sinc Interpolator</parameter>" or
|
|
||||||
"<parameter>3</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<application>libsamplerate</application>: Zero order
|
|
||||||
hold interpolator, very fast, very poor quality with
|
|
||||||
audible distortions.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
|
|
||||||
<row>
|
|
||||||
<entry>
|
|
||||||
"<parameter>Linear Interpolator</parameter>" or
|
|
||||||
"<parameter>4</parameter>"
|
|
||||||
</entry>
|
|
||||||
<entry>
|
|
||||||
<application>libsamplerate</application>: Linear
|
|
||||||
interpolator, very fast, poor quality.
|
|
||||||
</entry>
|
|
||||||
</row>
|
|
||||||
</tbody>
|
|
||||||
</tgroup>
|
|
||||||
</informaltable>
|
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
@ -2308,6 +2167,46 @@ buffer_size: 16384</programlisting>
|
||||||
<section id="resampler_plugins">
|
<section id="resampler_plugins">
|
||||||
<title>Resampler plugins</title>
|
<title>Resampler plugins</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The resampler can be configured in a block named
|
||||||
|
<varname>resampler</varname>, for example:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<programlisting>resampler {
|
||||||
|
plugin "soxr"
|
||||||
|
quality "very high"
|
||||||
|
}</programlisting>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following table lists the <varname>resampler</varname>
|
||||||
|
options valid for all plugins:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<informaltable>
|
||||||
|
<tgroup cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
Name
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Description
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<varname>plugin</varname>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
The name of the plugin.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</informaltable>
|
||||||
|
|
||||||
<section id="internal_resampler">
|
<section id="internal_resampler">
|
||||||
<title><varname>internal</varname></title>
|
<title><varname>internal</varname></title>
|
||||||
|
|
||||||
|
@ -2327,6 +2226,107 @@ buffer_size: 16384</programlisting>
|
||||||
url="http://www.mega-nerd.com/SRC/"><application>libsamplerate</application></ulink>
|
url="http://www.mega-nerd.com/SRC/"><application>libsamplerate</application></ulink>
|
||||||
a.k.a. Secret Rabbit Code (SRC).
|
a.k.a. Secret Rabbit Code (SRC).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<informaltable>
|
||||||
|
<tgroup cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
Name
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Description
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<varname>type</varname>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
The interpolator type. See below for a list of
|
||||||
|
known types.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</informaltable>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
The following converter types are provided by
|
||||||
|
<application>libsamplerate</application>:
|
||||||
|
</para>
|
||||||
|
|
||||||
|
<informaltable>
|
||||||
|
<tgroup cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
Type
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Description
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
"<parameter>Best Sinc Interpolator</parameter>" or
|
||||||
|
"<parameter>0</parameter>"
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Band limited sinc interpolation, best quality, 97dB
|
||||||
|
SNR, 96% BW.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
"<parameter>Medium Sinc Interpolator</parameter>" or
|
||||||
|
"<parameter>1</parameter>"
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Band limited sinc interpolation, medium quality,
|
||||||
|
97dB SNR, 90% BW.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
"<parameter>Fastest Sinc Interpolator</parameter>" or
|
||||||
|
"<parameter>2</parameter>"
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Band limited sinc interpolation, fastest, 97dB SNR,
|
||||||
|
80% BW.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
"<parameter>ZOH Sinc Interpolator</parameter>" or
|
||||||
|
"<parameter>3</parameter>"
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Zero order hold interpolator, very fast, very poor
|
||||||
|
quality with audible distortions.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
"<parameter>Linear Interpolator</parameter>" or
|
||||||
|
"<parameter>4</parameter>"
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Linear interpolator, very fast, poor quality.
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</informaltable>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="soxr_resampler">
|
<section id="soxr_resampler">
|
||||||
|
@ -2337,6 +2337,64 @@ buffer_size: 16384</programlisting>
|
||||||
url="http://sourceforge.net/projects/soxr/"><application>libsoxr</application></ulink>,
|
url="http://sourceforge.net/projects/soxr/"><application>libsoxr</application></ulink>,
|
||||||
the SoX Resampler library
|
the SoX Resampler library
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
|
<informaltable>
|
||||||
|
<tgroup cols="2">
|
||||||
|
<thead>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
Name
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
Description
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<row>
|
||||||
|
<entry>
|
||||||
|
<varname>quality</varname>
|
||||||
|
</entry>
|
||||||
|
<entry>
|
||||||
|
The <application>libsoxr</application> quality
|
||||||
|
setting. Valid values are:
|
||||||
|
|
||||||
|
<itemizedlist>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
"<parameter>very high</parameter>"
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
"<parameter>high</parameter>" (the default)
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
"<parameter>medium</parameter>"
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
"<parameter>low</parameter>"
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
"<parameter>quick</parameter>"
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</itemizedlist>
|
||||||
|
</entry>
|
||||||
|
</row>
|
||||||
|
</tbody>
|
||||||
|
</tgroup>
|
||||||
|
</informaltable>
|
||||||
</section>
|
</section>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
|
@ -86,6 +86,7 @@ enum class ConfigBlockOption {
|
||||||
DECODER,
|
DECODER,
|
||||||
INPUT,
|
INPUT,
|
||||||
PLAYLIST_PLUGIN,
|
PLAYLIST_PLUGIN,
|
||||||
|
RESAMPLER,
|
||||||
AUDIO_FILTER,
|
AUDIO_FILTER,
|
||||||
DATABASE,
|
DATABASE,
|
||||||
NEIGHBORS,
|
NEIGHBORS,
|
||||||
|
|
|
@ -86,6 +86,7 @@ const ConfigTemplate config_block_templates[] = {
|
||||||
{ "decoder", true },
|
{ "decoder", true },
|
||||||
{ "input", true },
|
{ "input", true },
|
||||||
{ "playlist_plugin", true },
|
{ "playlist_plugin", true },
|
||||||
|
{ "resampler", false },
|
||||||
{ "filter", true },
|
{ "filter", true },
|
||||||
{ "database", false },
|
{ "database", false },
|
||||||
{ "neighbors", true },
|
{ "neighbors", true },
|
||||||
|
|
|
@ -23,6 +23,8 @@
|
||||||
#include "config/ConfigGlobal.hxx"
|
#include "config/ConfigGlobal.hxx"
|
||||||
#include "config/ConfigOption.hxx"
|
#include "config/ConfigOption.hxx"
|
||||||
#include "config/ConfigError.hxx"
|
#include "config/ConfigError.hxx"
|
||||||
|
#include "config/Block.hxx"
|
||||||
|
#include "config/Param.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
|
||||||
#ifdef ENABLE_LIBSAMPLERATE
|
#ifdef ENABLE_LIBSAMPLERATE
|
||||||
|
@ -49,34 +51,119 @@ enum class SelectedResampler {
|
||||||
|
|
||||||
static SelectedResampler selected_resampler = SelectedResampler::FALLBACK;
|
static SelectedResampler selected_resampler = SelectedResampler::FALLBACK;
|
||||||
|
|
||||||
bool
|
static const ConfigBlock *
|
||||||
pcm_resampler_global_init(Error &error)
|
MakeResamplerDefaultConfig(ConfigBlock &block)
|
||||||
{
|
{
|
||||||
const char *converter =
|
assert(block.IsEmpty());
|
||||||
config_get_string(ConfigOption::SAMPLERATE_CONVERTER, "");
|
|
||||||
|
|
||||||
if (strcmp(converter, "internal") == 0)
|
#ifdef ENABLE_LIBSAMPLERATE
|
||||||
return true;
|
block.AddBlockParam("plugin", "libsamplerate");
|
||||||
|
#elif defined(ENABLE_SOXR)
|
||||||
|
block.AddBlockParam("plugin", "soxr");
|
||||||
|
#else
|
||||||
|
block.AddBlockParam("plugin", "internal");
|
||||||
|
#endif
|
||||||
|
return █
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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());
|
||||||
|
|
||||||
|
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
|
#ifdef ENABLE_SOXR
|
||||||
if (memcmp(converter, "soxr", 4) == 0) {
|
if (strcmp(converter, "soxr") == 0) {
|
||||||
selected_resampler = SelectedResampler::SOXR;
|
block.AddBlockParam("plugin", "soxr");
|
||||||
return pcm_resample_soxr_global_init(converter, error);
|
return █
|
||||||
|
}
|
||||||
|
|
||||||
|
if (memcmp(converter, "soxr ", 5) == 0) {
|
||||||
|
block.AddBlockParam("plugin", "soxr");
|
||||||
|
block.AddBlockParam("quality", converter + 5);
|
||||||
|
return █
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ENABLE_LIBSAMPLERATE
|
block.AddBlockParam("plugin", "libsamplerate");
|
||||||
selected_resampler = SelectedResampler::LIBSAMPLERATE;
|
block.AddBlockParam("type", converter);
|
||||||
return pcm_resample_lsr_global_init(converter, error);
|
return █
|
||||||
#endif
|
}
|
||||||
|
|
||||||
if (*converter == 0)
|
static const ConfigBlock *
|
||||||
|
MigrateResamplerConfig(const config_param *param, ConfigBlock &buffer)
|
||||||
|
{
|
||||||
|
assert(buffer.IsEmpty());
|
||||||
|
|
||||||
|
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;
|
return true;
|
||||||
|
#ifdef ENABLE_SOXR
|
||||||
error.Format(config_domain,
|
} else if (strcmp(plugin_name, "soxr") == 0) {
|
||||||
"The samplerate_converter '%s' is not available",
|
selected_resampler = SelectedResampler::SOXR;
|
||||||
converter);
|
return pcm_resample_soxr_global_init(*block, error);
|
||||||
return false;
|
#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 *
|
PcmResampler *
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "LibsamplerateResampler.hxx"
|
#include "LibsamplerateResampler.hxx"
|
||||||
|
#include "config/Block.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
|
@ -63,8 +64,9 @@ lsr_parse_converter(const char *s)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pcm_resample_lsr_global_init(const char *converter, Error &error)
|
pcm_resample_lsr_global_init(const ConfigBlock &block, Error &error)
|
||||||
{
|
{
|
||||||
|
const char *converter = block.GetBlockValue("type", "2");
|
||||||
if (!lsr_parse_converter(converter)) {
|
if (!lsr_parse_converter(converter)) {
|
||||||
error.Format(libsamplerate_domain,
|
error.Format(libsamplerate_domain,
|
||||||
"unknown samplerate converter '%s'", converter);
|
"unknown samplerate converter '%s'", converter);
|
||||||
|
|
|
@ -27,6 +27,8 @@
|
||||||
|
|
||||||
#include <samplerate.h>
|
#include <samplerate.h>
|
||||||
|
|
||||||
|
struct ConfigBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A resampler using libsamplerate.
|
* A resampler using libsamplerate.
|
||||||
*/
|
*/
|
||||||
|
@ -51,6 +53,6 @@ private:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pcm_resample_lsr_global_init(const char *converter, Error &error);
|
pcm_resample_lsr_global_init(const ConfigBlock &block, Error &error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "SoxrResampler.hxx"
|
#include "SoxrResampler.hxx"
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
|
#include "config/Block.hxx"
|
||||||
#include "util/ASCII.hxx"
|
#include "util/ASCII.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
#include "util/Domain.hxx"
|
#include "util/Domain.hxx"
|
||||||
|
@ -62,18 +63,11 @@ soxr_quality_name(unsigned long recipe)
|
||||||
|
|
||||||
gcc_pure
|
gcc_pure
|
||||||
static unsigned long
|
static unsigned long
|
||||||
soxr_parse_converter(const char *converter)
|
soxr_parse_quality(const char *quality)
|
||||||
{
|
{
|
||||||
assert(converter != nullptr);
|
if (quality == nullptr)
|
||||||
|
|
||||||
assert(memcmp(converter, "soxr", 4) == 0);
|
|
||||||
if (converter[4] == '\0')
|
|
||||||
return SOXR_DEFAULT_RECIPE;
|
return SOXR_DEFAULT_RECIPE;
|
||||||
if (converter[4] != ' ')
|
|
||||||
return SOXR_INVALID_RECIPE;
|
|
||||||
|
|
||||||
// converter example is "soxr very high", we want the "very high" part
|
|
||||||
const char *quality = converter + 5;
|
|
||||||
if (strcmp(quality, "very high") == 0)
|
if (strcmp(quality, "very high") == 0)
|
||||||
return SOXR_VHQ;
|
return SOXR_VHQ;
|
||||||
else if (strcmp(quality, "high") == 0)
|
else if (strcmp(quality, "high") == 0)
|
||||||
|
@ -89,12 +83,16 @@ soxr_parse_converter(const char *converter)
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pcm_resample_soxr_global_init(const char *converter, Error &error)
|
pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error)
|
||||||
{
|
{
|
||||||
unsigned long recipe = soxr_parse_converter(converter);
|
const char *quality_string = block.GetBlockValue("quality");
|
||||||
|
unsigned long recipe = soxr_parse_quality(quality_string);
|
||||||
if (recipe == SOXR_INVALID_RECIPE) {
|
if (recipe == SOXR_INVALID_RECIPE) {
|
||||||
|
assert(quality_string != nullptr);
|
||||||
|
|
||||||
error.Format(soxr_domain,
|
error.Format(soxr_domain,
|
||||||
"unknown samplerate converter '%s'", converter);
|
"unknown quality setting '%s' in line %d",
|
||||||
|
quality_string, block.line);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include "Compiler.h"
|
#include "Compiler.h"
|
||||||
|
|
||||||
struct AudioFormat;
|
struct AudioFormat;
|
||||||
|
struct ConfigBlock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A resampler using soxr.
|
* A resampler using soxr.
|
||||||
|
@ -46,6 +47,6 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
pcm_resample_soxr_global_init(const char *converter, Error &error);
|
pcm_resample_soxr_global_init(const ConfigBlock &block, Error &error);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -27,7 +27,6 @@
|
||||||
#include "AudioParser.hxx"
|
#include "AudioParser.hxx"
|
||||||
#include "AudioFormat.hxx"
|
#include "AudioFormat.hxx"
|
||||||
#include "pcm/PcmConvert.hxx"
|
#include "pcm/PcmConvert.hxx"
|
||||||
#include "config/ConfigGlobal.hxx"
|
|
||||||
#include "util/ConstBuffer.hxx"
|
#include "util/ConstBuffer.hxx"
|
||||||
#include "util/StaticFifoBuffer.hxx"
|
#include "util/StaticFifoBuffer.hxx"
|
||||||
#include "util/Error.hxx"
|
#include "util/Error.hxx"
|
||||||
|
@ -39,13 +38,6 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
const char *
|
|
||||||
config_get_string(gcc_unused enum ConfigOption option,
|
|
||||||
const char *default_value)
|
|
||||||
{
|
|
||||||
return default_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main(int argc, char **argv)
|
int main(int argc, char **argv)
|
||||||
{
|
{
|
||||||
AudioFormat in_audio_format, out_audio_format;
|
AudioFormat in_audio_format, out_audio_format;
|
||||||
|
|
Loading…
Reference in New Issue