diff options
Diffstat (limited to 'src/filter')
-rw-r--r-- | src/filter/FilterConfig.cxx | 80 | ||||
-rw-r--r-- | src/filter/FilterConfig.hxx | 43 | ||||
-rw-r--r-- | src/filter/FilterInternal.hxx | 74 | ||||
-rw-r--r-- | src/filter/FilterPlugin.cxx | 58 | ||||
-rw-r--r-- | src/filter/FilterPlugin.hxx | 67 | ||||
-rw-r--r-- | src/filter/FilterRegistry.cxx | 43 | ||||
-rw-r--r-- | src/filter/FilterRegistry.hxx | 43 | ||||
-rw-r--r-- | src/filter/plugins/AutoConvertFilterPlugin.cxx (renamed from src/filter/AutoConvertFilterPlugin.cxx) | 16 | ||||
-rw-r--r-- | src/filter/plugins/AutoConvertFilterPlugin.hxx (renamed from src/filter/AutoConvertFilterPlugin.hxx) | 2 | ||||
-rw-r--r-- | src/filter/plugins/ChainFilterPlugin.cxx (renamed from src/filter/ChainFilterPlugin.cxx) | 8 | ||||
-rw-r--r-- | src/filter/plugins/ChainFilterPlugin.hxx (renamed from src/filter/ChainFilterPlugin.hxx) | 2 | ||||
-rw-r--r-- | src/filter/plugins/ConvertFilterPlugin.cxx (renamed from src/filter/ConvertFilterPlugin.cxx) | 74 | ||||
-rw-r--r-- | src/filter/plugins/ConvertFilterPlugin.hxx (renamed from src/filter/ConvertFilterPlugin.hxx) | 8 | ||||
-rw-r--r-- | src/filter/plugins/NormalizeFilterPlugin.cxx (renamed from src/filter/NormalizeFilterPlugin.cxx) | 9 | ||||
-rw-r--r-- | src/filter/plugins/NullFilterPlugin.cxx (renamed from src/filter/NullFilterPlugin.cxx) | 8 | ||||
-rw-r--r-- | src/filter/plugins/ReplayGainFilterPlugin.cxx (renamed from src/filter/ReplayGainFilterPlugin.cxx) | 71 | ||||
-rw-r--r-- | src/filter/plugins/ReplayGainFilterPlugin.hxx (renamed from src/filter/ReplayGainFilterPlugin.hxx) | 2 | ||||
-rw-r--r-- | src/filter/plugins/RouteFilterPlugin.cxx (renamed from src/filter/RouteFilterPlugin.cxx) | 13 | ||||
-rw-r--r-- | src/filter/plugins/VolumeFilterPlugin.cxx (renamed from src/filter/VolumeFilterPlugin.cxx) | 73 | ||||
-rw-r--r-- | src/filter/plugins/VolumeFilterPlugin.hxx (renamed from src/filter/VolumeFilterPlugin.hxx) | 2 |
20 files changed, 538 insertions, 158 deletions
diff --git a/src/filter/FilterConfig.cxx b/src/filter/FilterConfig.cxx new file mode 100644 index 000000000..d8c1fc6c2 --- /dev/null +++ b/src/filter/FilterConfig.cxx @@ -0,0 +1,80 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "FilterConfig.hxx" +#include "plugins/ChainFilterPlugin.hxx" +#include "FilterPlugin.hxx" +#include "config/ConfigData.hxx" +#include "config/ConfigOption.hxx" +#include "config/ConfigGlobal.hxx" +#include "config/ConfigError.hxx" +#include "util/Error.hxx" + +#include <algorithm> + +#include <string.h> + +static bool +filter_chain_append_new(Filter &chain, const char *template_name, Error &error) +{ + const struct config_param *cfg = + config_find_block(CONF_AUDIO_FILTER, "name", template_name); + if (cfg == nullptr) { + error.Format(config_domain, + "filter template not found: %s", + template_name); + return false; + } + + // Instantiate one of those filter plugins with the template name as a hint + Filter *f = filter_configured_new(*cfg, error); + if (f == nullptr) + // The error has already been set, just stop. + return false; + + const char *plugin_name = cfg->GetBlockValue("plugin", + "unknown"); + filter_chain_append(chain, plugin_name, f); + + return true; +} + +bool +filter_chain_parse(Filter &chain, const char *spec, Error &error) +{ + const char *const end = spec + strlen(spec); + + while (true) { + const char *comma = std::find(spec, end, ','); + if (comma > spec) { + const std::string name(spec, comma); + if (!filter_chain_append_new(chain, name.c_str(), + error)) + return false; + } + + if (comma == end) + break; + + spec = comma + 1; + } + + return true; +} diff --git a/src/filter/FilterConfig.hxx b/src/filter/FilterConfig.hxx new file mode 100644 index 000000000..1018eed51 --- /dev/null +++ b/src/filter/FilterConfig.hxx @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** \file + * + * Utility functions for filter configuration + */ + +#ifndef MPD_FILTER_CONFIG_HXX +#define MPD_FILTER_CONFIG_HXX + +class Filter; +class Error; + +/** + * Builds a filter chain from a configuration string on the form + * "name1, name2, name3, ..." by looking up each name among the + * configured filter sections. + * @param chain the chain to append filters on + * @param spec the filter chain specification + * @param error_r space to return an error description + * @return true on success + */ +bool +filter_chain_parse(Filter &chain, const char *spec, Error &error); + +#endif diff --git a/src/filter/FilterInternal.hxx b/src/filter/FilterInternal.hxx new file mode 100644 index 000000000..131c3b3f5 --- /dev/null +++ b/src/filter/FilterInternal.hxx @@ -0,0 +1,74 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** \file + * + * Internal stuff for the filter core and filter plugins. + */ + +#ifndef MPD_FILTER_INTERNAL_HXX +#define MPD_FILTER_INTERNAL_HXX + +#include <stddef.h> + +struct AudioFormat; +class Error; + +class Filter { +public: + virtual ~Filter() {} + + /** + * Opens the filter, preparing it for FilterPCM(). + * + * @param filter the filter object + * @param audio_format the audio format of incoming data; the + * plugin may modify the object to enforce another input + * format + * @param error location to store the error occurring, or nullptr + * to ignore errors. + * @return the format of outgoing data or + * AudioFormat::Undefined() on error + */ + virtual AudioFormat Open(AudioFormat &af, Error &error) = 0; + + /** + * Closes the filter. After that, you may call Open() again. + */ + virtual void Close() = 0; + + /** + * Filters a block of PCM data. + * + * @param filter the filter object + * @param src the input buffer + * @param src_size the size of #src_buffer in bytes + * @param dest_size_r the size of the returned buffer + * @param error location to store the error occurring, or nullptr + * to ignore errors. + * @return the destination buffer on success (will be + * invalidated by filter_close() or filter_filter()), nullptr on + * error + */ + virtual const void *FilterPCM(const void *src, size_t src_size, + size_t *dest_size_r, + Error &error) = 0; +}; + +#endif diff --git a/src/filter/FilterPlugin.cxx b/src/filter/FilterPlugin.cxx new file mode 100644 index 000000000..98314f771 --- /dev/null +++ b/src/filter/FilterPlugin.cxx @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "FilterPlugin.hxx" +#include "FilterRegistry.hxx" +#include "config/ConfigData.hxx" +#include "config/ConfigError.hxx" +#include "util/Error.hxx" + +#include <assert.h> + +Filter * +filter_new(const struct filter_plugin *plugin, + const config_param ¶m, Error &error) +{ + assert(plugin != nullptr); + assert(!error.IsDefined()); + + return plugin->init(param, error); +} + +Filter * +filter_configured_new(const config_param ¶m, Error &error) +{ + assert(!error.IsDefined()); + + const char *plugin_name = param.GetBlockValue("plugin"); + if (plugin_name == nullptr) { + error.Set(config_domain, "No filter plugin specified"); + return nullptr; + } + + const filter_plugin *plugin = filter_plugin_by_name(plugin_name); + if (plugin == nullptr) { + error.Format(config_domain, + "No such filter plugin: %s", plugin_name); + return nullptr; + } + + return filter_new(plugin, param, error); +} diff --git a/src/filter/FilterPlugin.hxx b/src/filter/FilterPlugin.hxx new file mode 100644 index 000000000..443d29881 --- /dev/null +++ b/src/filter/FilterPlugin.hxx @@ -0,0 +1,67 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** \file + * + * This header declares the filter_plugin class. It describes a + * plugin API for objects which filter raw PCM data. + */ + +#ifndef MPD_FILTER_PLUGIN_HXX +#define MPD_FILTER_PLUGIN_HXX + +struct config_param; +class Filter; +class Error; + +struct filter_plugin { + const char *name; + + /** + * Allocates and configures a filter. + */ + Filter *(*init)(const config_param ¶m, Error &error); +}; + +/** + * Creates a new instance of the specified filter plugin. + * + * @param plugin the filter plugin + * @param param optional configuration section + * @param error location to store the error occurring, or nullptr to + * ignore errors. + * @return a new filter object, or nullptr on error + */ +Filter * +filter_new(const struct filter_plugin *plugin, + const config_param ¶m, Error &error); + +/** + * Creates a new filter, loads configuration and the plugin name from + * the specified configuration section. + * + * @param param the configuration section + * @param error location to store the error occurring, or nullptr to + * ignore errors. + * @return a new filter object, or nullptr on error + */ +Filter * +filter_configured_new(const config_param ¶m, Error &error); + +#endif diff --git a/src/filter/FilterRegistry.cxx b/src/filter/FilterRegistry.cxx new file mode 100644 index 000000000..286fb8db3 --- /dev/null +++ b/src/filter/FilterRegistry.cxx @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include "config.h" +#include "FilterRegistry.hxx" +#include "FilterPlugin.hxx" + +#include <string.h> + +const struct filter_plugin *const filter_plugins[] = { + &null_filter_plugin, + &route_filter_plugin, + &normalize_filter_plugin, + &volume_filter_plugin, + &replay_gain_filter_plugin, + nullptr, +}; + +const struct filter_plugin * +filter_plugin_by_name(const char *name) +{ + for (unsigned i = 0; filter_plugins[i] != nullptr; ++i) + if (strcmp(filter_plugins[i]->name, name) == 0) + return filter_plugins[i]; + + return nullptr; +} diff --git a/src/filter/FilterRegistry.hxx b/src/filter/FilterRegistry.hxx new file mode 100644 index 000000000..24618a87a --- /dev/null +++ b/src/filter/FilterRegistry.hxx @@ -0,0 +1,43 @@ +/* + * Copyright (C) 2003-2014 The Music Player Daemon Project + * http://www.musicpd.org + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +/** \file + * + * This library manages all filter plugins which are enabled at + * compile time. + */ + +#ifndef MPD_FILTER_REGISTRY_HXX +#define MPD_FILTER_REGISTRY_HXX + +#include "Compiler.h" + +extern const struct filter_plugin null_filter_plugin; +extern const struct filter_plugin chain_filter_plugin; +extern const struct filter_plugin convert_filter_plugin; +extern const struct filter_plugin route_filter_plugin; +extern const struct filter_plugin normalize_filter_plugin; +extern const struct filter_plugin volume_filter_plugin; +extern const struct filter_plugin replay_gain_filter_plugin; + +gcc_pure +const struct filter_plugin * +filter_plugin_by_name(const char *name); + +#endif diff --git a/src/filter/AutoConvertFilterPlugin.cxx b/src/filter/plugins/AutoConvertFilterPlugin.cxx index 918a16e53..cdeeefdc6 100644 --- a/src/filter/AutoConvertFilterPlugin.cxx +++ b/src/filter/plugins/AutoConvertFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -20,11 +20,11 @@ #include "config.h" #include "AutoConvertFilterPlugin.hxx" #include "ConvertFilterPlugin.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "AudioFormat.hxx" -#include "ConfigData.hxx" +#include "config/ConfigData.hxx" #include <assert.h> @@ -88,7 +88,11 @@ AutoConvertFilter::Open(AudioFormat &in_audio_format, Error &error) assert(audio_format2 == in_audio_format); - convert_filter_set(convert, child_audio_format); + if (!convert_filter_set(convert, child_audio_format, error)) { + delete convert; + filter->Close(); + return AudioFormat::Undefined(); + } } else /* no */ convert = nullptr; diff --git a/src/filter/AutoConvertFilterPlugin.hxx b/src/filter/plugins/AutoConvertFilterPlugin.hxx index 7db72a345..c5dfdd2f6 100644 --- a/src/filter/AutoConvertFilterPlugin.hxx +++ b/src/filter/plugins/AutoConvertFilterPlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/filter/ChainFilterPlugin.cxx b/src/filter/plugins/ChainFilterPlugin.cxx index cb52b86ca..7dc6db667 100644 --- a/src/filter/ChainFilterPlugin.cxx +++ b/src/filter/plugins/ChainFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,9 +19,9 @@ #include "config.h" #include "ChainFilterPlugin.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "AudioFormat.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" diff --git a/src/filter/ChainFilterPlugin.hxx b/src/filter/plugins/ChainFilterPlugin.hxx index 884c7ca19..b36aa3322 100644 --- a/src/filter/ChainFilterPlugin.hxx +++ b/src/filter/plugins/ChainFilterPlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/filter/ConvertFilterPlugin.cxx b/src/filter/plugins/ConvertFilterPlugin.cxx index 040f8426f..27e6774f8 100644 --- a/src/filter/ConvertFilterPlugin.cxx +++ b/src/filter/plugins/ConvertFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,16 +19,15 @@ #include "config.h" #include "ConvertFilterPlugin.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "pcm/PcmConvert.hxx" #include "util/Manual.hxx" #include "AudioFormat.hxx" #include "poison.h" #include <assert.h> -#include <string.h> class ConvertFilter final : public Filter { /** @@ -39,21 +38,18 @@ class ConvertFilter final : public Filter { /** * The output audio format; the consumer of this plugin - * expects PCM data in this format. This defaults to - * #in_audio_format, and can be set with convert_filter_set(). + * expects PCM data in this format. + * + * If this is AudioFormat::Undefined(), then the #PcmConvert + * attribute is not open. This can mean that Set() has failed + * or that no conversion is necessary. */ AudioFormat out_audio_format; Manual<PcmConvert> state; public: - void Set(const AudioFormat &_out_audio_format) { - assert(in_audio_format.IsValid()); - assert(out_audio_format.IsValid()); - assert(_out_audio_format.IsValid()); - - out_audio_format = _out_audio_format; - } + bool Set(const AudioFormat &_out_audio_format, Error &error); virtual AudioFormat Open(AudioFormat &af, Error &error) override; virtual void Close() override; @@ -69,12 +65,40 @@ convert_filter_init(gcc_unused const config_param ¶m, return new ConvertFilter(); } +bool +ConvertFilter::Set(const AudioFormat &_out_audio_format, Error &error) +{ + assert(in_audio_format.IsValid()); + assert(_out_audio_format.IsValid()); + + if (_out_audio_format == out_audio_format) + /* no change */ + return true; + + if (out_audio_format.IsValid()) { + out_audio_format.Clear(); + state->Close(); + } + + if (_out_audio_format == in_audio_format) + /* optimized special case: no-op */ + return true; + + if (!state->Open(in_audio_format, _out_audio_format, error)) + return false; + + out_audio_format = _out_audio_format; + return true; +} + AudioFormat ConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error) { assert(audio_format.IsValid()); - in_audio_format = out_audio_format = audio_format; + in_audio_format = audio_format; + out_audio_format.Clear(); + state.Construct(); return in_audio_format; @@ -83,6 +107,11 @@ ConvertFilter::Open(AudioFormat &audio_format, gcc_unused Error &error) void ConvertFilter::Close() { + assert(in_audio_format.IsValid()); + + if (out_audio_format.IsValid()) + state->Close(); + state.Destruct(); poison_undefined(&in_audio_format, sizeof(in_audio_format)); @@ -93,15 +122,15 @@ const void * ConvertFilter::FilterPCM(const void *src, size_t src_size, size_t *dest_size_r, Error &error) { - if (in_audio_format == out_audio_format) { + assert(in_audio_format.IsValid()); + + if (!out_audio_format.IsValid()) { /* optimized special case: no-op */ *dest_size_r = src_size; return src; } - return state->Convert(in_audio_format, - src, src_size, - out_audio_format, dest_size_r, + return state->Convert(src, src_size, dest_size_r, error); } @@ -110,10 +139,11 @@ const struct filter_plugin convert_filter_plugin = { convert_filter_init, }; -void -convert_filter_set(Filter *_filter, const AudioFormat out_audio_format) +bool +convert_filter_set(Filter *_filter, AudioFormat out_audio_format, + Error &error) { ConvertFilter *filter = (ConvertFilter *)_filter; - filter->Set(out_audio_format); + return filter->Set(out_audio_format, error); } diff --git a/src/filter/ConvertFilterPlugin.hxx b/src/filter/plugins/ConvertFilterPlugin.hxx index c814aaf49..bb4673651 100644 --- a/src/filter/ConvertFilterPlugin.hxx +++ b/src/filter/plugins/ConvertFilterPlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -21,6 +21,7 @@ #define MPD_CONVERT_FILTER_PLUGIN_HXX class Filter; +class Error; struct AudioFormat; /** @@ -29,7 +30,8 @@ struct AudioFormat; * format switch is a violation of the filter API, this filter must be * the last in a chain. */ -void -convert_filter_set(Filter *filter, AudioFormat out_audio_format); +bool +convert_filter_set(Filter *filter, AudioFormat out_audio_format, + Error &error); #endif diff --git a/src/filter/NormalizeFilterPlugin.cxx b/src/filter/plugins/NormalizeFilterPlugin.cxx index 6c4f6b0e5..58eb0c6a2 100644 --- a/src/filter/NormalizeFilterPlugin.cxx +++ b/src/filter/plugins/NormalizeFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -18,14 +18,13 @@ */ #include "config.h" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "pcm/PcmBuffer.hxx" #include "AudioFormat.hxx" #include "AudioCompress/compress.h" -#include <assert.h> #include <string.h> class NormalizeFilter final : public Filter { diff --git a/src/filter/NullFilterPlugin.cxx b/src/filter/plugins/NullFilterPlugin.cxx index c762592f6..f79aa19f7 100644 --- a/src/filter/NullFilterPlugin.cxx +++ b/src/filter/plugins/NullFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -25,9 +25,9 @@ */ #include "config.h" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "AudioFormat.hxx" #include "Compiler.h" diff --git a/src/filter/ReplayGainFilterPlugin.cxx b/src/filter/plugins/ReplayGainFilterPlugin.cxx index b2dcde4cc..a5d9668cc 100644 --- a/src/filter/ReplayGainFilterPlugin.cxx +++ b/src/filter/plugins/ReplayGainFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,15 +19,16 @@ #include "config.h" #include "ReplayGainFilterPlugin.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "AudioFormat.hxx" #include "ReplayGainInfo.hxx" #include "ReplayGainConfig.hxx" -#include "MixerControl.hxx" -#include "pcm/PcmVolume.hxx" +#include "mixer/MixerControl.hxx" +#include "pcm/Volume.hxx" #include "pcm/PcmBuffer.hxx" +#include "util/ConstBuffer.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" #include "Log.hxx" @@ -55,8 +56,8 @@ class ReplayGainFilter final : public Filter { ReplayGainInfo info; /** - * The current volume, between 0 and a value that may or may not exceed - * #PCM_VOLUME_1. + * About the current volume: it is between 0 and a value that + * may or may not exceed #PCM_VOLUME_1. * * If the default value of true is used for replaygain_limit, the * application of the volume to the signal will never cause clipping. @@ -66,16 +67,11 @@ class ReplayGainFilter final : public Filter { * maintain a consistent audio level. Whether clipping will actually * occur depends on what value the user is using for replaygain_preamp. */ - unsigned volume; - - AudioFormat format; - - PcmBuffer buffer; + PcmVolume pv; public: ReplayGainFilter() - :mixer(nullptr), mode(REPLAY_GAIN_OFF), - volume(PCM_VOLUME_1) { + :mixer(nullptr), mode(REPLAY_GAIN_OFF) { info.Clear(); } @@ -125,6 +121,7 @@ public: void ReplayGainFilter::Update() { + unsigned volume = PCM_VOLUME_1; if (mode != REPLAY_GAIN_OFF) { const auto &tuple = info.tuples[mode]; float scale = tuple.CalculateScale(replay_gain_preamp, @@ -134,8 +131,9 @@ ReplayGainFilter::Update() "scale=%f\n", (double)scale); volume = pcm_float_to_volume(scale); - } else - volume = PCM_VOLUME_1; + } + + pv.SetVolume(volume); if (mixer != nullptr) { /* update the hardware mixer volume */ @@ -160,48 +158,25 @@ replay_gain_filter_init(gcc_unused const config_param ¶m, AudioFormat ReplayGainFilter::Open(AudioFormat &af, gcc_unused Error &error) { - format = af; + if (!pv.Open(af.format, error)) + return AudioFormat::Undefined(); - return format; + return af; } void ReplayGainFilter::Close() { - buffer.Clear(); + pv.Close(); } const void * ReplayGainFilter::FilterPCM(const void *src, size_t src_size, - size_t *dest_size_r, Error &error) + size_t *dest_size_r, gcc_unused Error &error) { - - *dest_size_r = src_size; - - if (volume == PCM_VOLUME_1) - /* optimized special case: 100% volume = no-op */ - return src; - - void *dest = buffer.Get(src_size); - if (volume <= 0) { - /* optimized special case: 0% volume = memset(0) */ - /* XXX is this valid for all sample formats? What - about floating point? */ - memset(dest, 0, src_size); - return dest; - } - - memcpy(dest, src, src_size); - - bool success = pcm_volume(dest, src_size, - format.format, - volume); - if (!success) { - error.Set(replay_gain_domain, "pcm_volume() has failed"); - return nullptr; - } - - return dest; + const auto dest = pv.Apply({src, src_size}); + *dest_size_r = dest.size; + return dest.data; } const struct filter_plugin replay_gain_filter_plugin = { diff --git a/src/filter/ReplayGainFilterPlugin.hxx b/src/filter/plugins/ReplayGainFilterPlugin.hxx index fbd1f2712..346541b97 100644 --- a/src/filter/ReplayGainFilterPlugin.hxx +++ b/src/filter/plugins/ReplayGainFilterPlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify diff --git a/src/filter/RouteFilterPlugin.cxx b/src/filter/plugins/RouteFilterPlugin.cxx index d9042c21f..38c4ec43b 100644 --- a/src/filter/RouteFilterPlugin.cxx +++ b/src/filter/plugins/RouteFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -40,13 +40,12 @@ */ #include "config.h" -#include "ConfigError.hxx" -#include "ConfigData.hxx" +#include "config/ConfigError.hxx" +#include "config/ConfigData.hxx" #include "AudioFormat.hxx" -#include "CheckAudioFormat.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" #include "pcm/PcmBuffer.hxx" #include "util/StringUtil.hxx" #include "util/Error.hxx" diff --git a/src/filter/VolumeFilterPlugin.cxx b/src/filter/plugins/VolumeFilterPlugin.cxx index 1b663f6eb..c9b7aa89e 100644 --- a/src/filter/VolumeFilterPlugin.cxx +++ b/src/filter/plugins/VolumeFilterPlugin.cxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify @@ -19,12 +19,12 @@ #include "config.h" #include "VolumeFilterPlugin.hxx" -#include "FilterPlugin.hxx" -#include "FilterInternal.hxx" -#include "FilterRegistry.hxx" -#include "pcm/PcmVolume.hxx" -#include "pcm/PcmBuffer.hxx" +#include "filter/FilterPlugin.hxx" +#include "filter/FilterInternal.hxx" +#include "filter/FilterRegistry.hxx" +#include "pcm/Volume.hxx" #include "AudioFormat.hxx" +#include "util/ConstBuffer.hxx" #include "util/Error.hxx" #include "util/Domain.hxx" @@ -32,29 +32,15 @@ #include <string.h> class VolumeFilter final : public Filter { - /** - * The current volume, from 0 to #PCM_VOLUME_1. - */ - unsigned volume; - - AudioFormat format; - - PcmBuffer buffer; + PcmVolume pv; public: - VolumeFilter() - :volume(PCM_VOLUME_1) {} - unsigned GetVolume() const { - assert(volume <= PCM_VOLUME_1); - - return volume; + return pv.GetVolume(); } void SetVolume(unsigned _volume) { - assert(_volume <= PCM_VOLUME_1); - - volume = _volume; + pv.SetVolume(_volume); } virtual AudioFormat Open(AudioFormat &af, Error &error) override; @@ -73,50 +59,27 @@ volume_filter_init(gcc_unused const config_param ¶m, } AudioFormat -VolumeFilter::Open(AudioFormat &audio_format, gcc_unused Error &error) +VolumeFilter::Open(AudioFormat &audio_format, Error &error) { - format = audio_format; + if (!pv.Open(audio_format.format, error)) + return AudioFormat::Undefined(); - return format; + return audio_format; } void VolumeFilter::Close() { - buffer.Clear(); + pv.Close(); } const void * VolumeFilter::FilterPCM(const void *src, size_t src_size, - size_t *dest_size_r, Error &error) + size_t *dest_size_r, gcc_unused Error &error) { - *dest_size_r = src_size; - - if (volume >= PCM_VOLUME_1) - /* optimized special case: 100% volume = no-op */ - return src; - - void *dest = buffer.Get(src_size); - - if (volume <= 0) { - /* optimized special case: 0% volume = memset(0) */ - /* XXX is this valid for all sample formats? What - about floating point? */ - memset(dest, 0, src_size); - return dest; - } - - memcpy(dest, src, src_size); - - bool success = pcm_volume(dest, src_size, - format.format, - volume); - if (!success) { - error.Set(volume_domain, "pcm_volume() has failed"); - return NULL; - } - - return dest; + const auto dest = pv.Apply({src, src_size}); + *dest_size_r = dest.size; + return dest.data; } const struct filter_plugin volume_filter_plugin = { diff --git a/src/filter/VolumeFilterPlugin.hxx b/src/filter/plugins/VolumeFilterPlugin.hxx index 822b7e93a..b5317dc6f 100644 --- a/src/filter/VolumeFilterPlugin.hxx +++ b/src/filter/plugins/VolumeFilterPlugin.hxx @@ -1,5 +1,5 @@ /* - * Copyright (C) 2003-2013 The Music Player Daemon Project + * Copyright (C) 2003-2014 The Music Player Daemon Project * http://www.musicpd.org * * This program is free software; you can redistribute it and/or modify |