From 3894450b10baeaa17c871cb5dc1a0961e0726fae Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 1 Feb 2013 17:47:09 +0100 Subject: filter: convert to C++ --- Makefile.am | 23 +-- src/FilterConfig.cxx | 12 +- src/FilterInternal.hxx | 38 ++++ src/FilterPlugin.cxx | 117 +++++++++++ src/FilterPlugin.hxx | 149 ++++++++++++++ src/FilterRegistry.cxx | 44 +++++ src/FilterRegistry.hxx | 40 ++++ src/OutputControl.cxx | 2 +- src/OutputFinish.cxx | 3 +- src/OutputInit.cxx | 6 +- src/OutputThread.cxx | 2 +- src/filter/AutoConvertFilterPlugin.cxx | 6 +- src/filter/ChainFilterPlugin.cxx | 214 ++++++++++++++++++++ src/filter/ChainFilterPlugin.hxx | 48 +++++ src/filter/ConvertFilterPlugin.cxx | 6 +- src/filter/NormalizeFilterPlugin.cxx | 111 +++++++++++ src/filter/NullFilterPlugin.cxx | 94 +++++++++ src/filter/ReplayGainFilterPlugin.cxx | 6 +- src/filter/RouteFilterPlugin.cxx | 350 +++++++++++++++++++++++++++++++++ src/filter/VolumeFilterPlugin.cxx | 6 +- src/filter/chain_filter_plugin.c | 215 -------------------- src/filter/chain_filter_plugin.h | 48 ----- src/filter/normalize_filter_plugin.c | 112 ----------- src/filter/null_filter_plugin.c | 94 --------- src/filter/route_filter_plugin.c | 349 -------------------------------- src/filter_internal.h | 38 ---- src/filter_plugin.c | 117 ----------- src/filter_plugin.h | 158 --------------- src/filter_registry.c | 44 ----- src/filter_registry.h | 40 ---- src/mixer/SoftwareMixerPlugin.cxx | 4 +- test/read_mixer.cxx | 2 +- test/run_filter.cxx | 2 +- test/run_output.cxx | 2 +- 34 files changed, 1243 insertions(+), 1259 deletions(-) create mode 100644 src/FilterInternal.hxx create mode 100644 src/FilterPlugin.cxx create mode 100644 src/FilterPlugin.hxx create mode 100644 src/FilterRegistry.cxx create mode 100644 src/FilterRegistry.hxx create mode 100644 src/filter/ChainFilterPlugin.cxx create mode 100644 src/filter/ChainFilterPlugin.hxx create mode 100644 src/filter/NormalizeFilterPlugin.cxx create mode 100644 src/filter/NullFilterPlugin.cxx create mode 100644 src/filter/RouteFilterPlugin.cxx delete mode 100644 src/filter/chain_filter_plugin.c delete mode 100644 src/filter/chain_filter_plugin.h delete mode 100644 src/filter/normalize_filter_plugin.c delete mode 100644 src/filter/null_filter_plugin.c delete mode 100644 src/filter/route_filter_plugin.c delete mode 100644 src/filter_internal.h delete mode 100644 src/filter_plugin.c delete mode 100644 src/filter_plugin.h delete mode 100644 src/filter_registry.c delete mode 100644 src/filter_registry.h diff --git a/Makefile.am b/Makefile.am index de818855..0e770efe 100644 --- a/Makefile.am +++ b/Makefile.am @@ -57,9 +57,6 @@ mpd_headers = \ src/output_internal.h \ src/output_api.h \ src/filter_internal.h \ - src/filter_plugin.h \ - src/filter_registry.h \ - src/filter/chain_filter_plugin.h \ src/command.h \ src/conf.h \ src/decoder_plugin.h \ @@ -168,8 +165,8 @@ src_mpd_SOURCES = \ src/ExcludeList.cxx src/ExcludeList.hxx \ src/fd_util.c \ src/FilterConfig.cxx src/FilterConfig.hxx \ - src/filter_plugin.c \ - src/filter_registry.c \ + src/FilterPlugin.cxx src/FilterPlugin.hxx \ + src/FilterRegistry.cxx src/FilterRegistry.hxx \ src/UpdateGlue.cxx src/UpdateGlue.hxx \ src/UpdateQueue.cxx src/UpdateQueue.hxx \ src/UpdateIO.cxx src/UpdateIO.hxx \ @@ -968,14 +965,15 @@ endif # libfilter_plugins_a_SOURCES = \ - src/filter/null_filter_plugin.c \ - src/filter/chain_filter_plugin.c \ + src/filter/NullFilterPlugin.cxx \ + src/filter/ChainFilterPlugin.cxx \ + src/filter/ChainFilterPlugin.hxx \ src/filter/AutoConvertFilterPlugin.cxx \ src/filter/AutoConvertFilterPlugin.hxx \ src/filter/ConvertFilterPlugin.cxx \ src/filter/ConvertFilterPlugin.hxx \ - src/filter/route_filter_plugin.c \ - src/filter/normalize_filter_plugin.c \ + src/filter/RouteFilterPlugin.cxx \ + src/filter/NormalizeFilterPlugin.cxx \ src/filter/ReplayGainFilterPlugin.cxx \ src/filter/ReplayGainFilterPlugin.hxx \ src/filter/VolumeFilterPlugin.cxx \ @@ -1239,8 +1237,7 @@ test_run_filter_LDADD = \ test_run_filter_SOURCES = test/run_filter.cxx \ test/FakeReplayGainConfig.cxx \ test/stdbin.h \ - src/filter_plugin.c \ - src/filter_registry.c \ + src/FilterPlugin.cxx src/FilterRegistry.cxx \ src/tokenizer.c src/utils.c src/string_util.c \ src/audio_check.c \ src/audio_format.c \ @@ -1350,7 +1347,7 @@ test_run_output_SOURCES = test/run_output.cxx \ src/mixer_api.c \ src/mixer_control.c \ src/mixer_type.c \ - src/filter_plugin.c \ + src/FilterPlugin.cxx \ src/FilterConfig.cxx \ src/AudioCompress/compress.c \ src/ReplayGainInfo.cxx \ @@ -1367,7 +1364,7 @@ test_read_mixer_LDADD = \ test_read_mixer_SOURCES = test/read_mixer.cxx \ src/tokenizer.c src/utils.c src/string_util.c \ src/mixer_control.c src/mixer_api.c \ - src/filter_plugin.c \ + src/FilterPlugin.cxx \ src/filter/VolumeFilterPlugin.cxx \ src/fd_util.c diff --git a/src/FilterConfig.cxx b/src/FilterConfig.cxx index 8d4dc577..7fca2ae6 100644 --- a/src/FilterConfig.cxx +++ b/src/FilterConfig.cxx @@ -20,14 +20,10 @@ #include "config.h" #include "FilterConfig.hxx" #include "conf.h" - -extern "C" { -#include "filter/chain_filter_plugin.h" -} - -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" +#include "filter/ChainFilterPlugin.hxx" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" #include diff --git a/src/FilterInternal.hxx b/src/FilterInternal.hxx new file mode 100644 index 00000000..7ffcec33 --- /dev/null +++ b/src/FilterInternal.hxx @@ -0,0 +1,38 @@ +/* + * Copyright (C) 2003-2013 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 + +struct filter { + const struct filter_plugin *plugin; +}; + +static inline void +filter_init(struct filter *filter, const struct filter_plugin *plugin) +{ + filter->plugin = plugin; +} + +#endif diff --git a/src/FilterPlugin.cxx b/src/FilterPlugin.cxx new file mode 100644 index 00000000..f1f7561a --- /dev/null +++ b/src/FilterPlugin.cxx @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2003-2013 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 "FilterInternal.hxx" +#include "FilterRegistry.hxx" +#include "conf.h" +#include "ConfigQuark.hxx" + +#ifndef NDEBUG +#include "audio_format.h" +#endif + +#include + +struct filter * +filter_new(const struct filter_plugin *plugin, + const struct config_param *param, GError **error_r) +{ + assert(plugin != NULL); + assert(error_r == NULL || *error_r == NULL); + + return plugin->init(param, error_r); +} + +struct filter * +filter_configured_new(const struct config_param *param, GError **error_r) +{ + const char *plugin_name; + const struct filter_plugin *plugin; + + assert(param != NULL); + assert(error_r == NULL || *error_r == NULL); + + plugin_name = config_get_block_string(param, "plugin", NULL); + if (plugin_name == NULL) { + g_set_error(error_r, config_quark(), 0, + "No filter plugin specified"); + return NULL; + } + + plugin = filter_plugin_by_name(plugin_name); + if (plugin == NULL) { + g_set_error(error_r, config_quark(), 0, + "No such filter plugin: %s", plugin_name); + return NULL; + } + + return filter_new(plugin, param, error_r); +} + +void +filter_free(struct filter *filter) +{ + assert(filter != NULL); + + filter->plugin->finish(filter); +} + +const struct audio_format * +filter_open(struct filter *filter, struct audio_format *audio_format, + GError **error_r) +{ + const struct audio_format *out_audio_format; + + assert(filter != NULL); + assert(audio_format != NULL); + assert(audio_format_valid(audio_format)); + assert(error_r == NULL || *error_r == NULL); + + out_audio_format = filter->plugin->open(filter, audio_format, error_r); + + assert(out_audio_format == NULL || audio_format_valid(audio_format)); + assert(out_audio_format == NULL || + audio_format_valid(out_audio_format)); + + return out_audio_format; +} + +void +filter_close(struct filter *filter) +{ + assert(filter != NULL); + + filter->plugin->close(filter); +} + +const void * +filter_filter(struct filter *filter, const void *src, size_t src_size, + size_t *dest_size_r, + GError **error_r) +{ + assert(filter != NULL); + assert(src != NULL); + assert(src_size > 0); + assert(dest_size_r != NULL); + assert(error_r == NULL || *error_r == NULL); + + return filter->plugin->filter(filter, src, src_size, dest_size_r, error_r); +} diff --git a/src/FilterPlugin.hxx b/src/FilterPlugin.hxx new file mode 100644 index 00000000..6476a621 --- /dev/null +++ b/src/FilterPlugin.hxx @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2003-2013 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 + +#include "gerror.h" + +#include + +struct config_param; +struct filter; + +struct filter_plugin { + const char *name; + + /** + * Allocates and configures a filter. + */ + struct filter *(*init)(const struct config_param *param, + GError **error_r); + + /** + * Free instance data. + */ + void (*finish)(struct filter *filter); + + /** + * Opens a filter. + * + * @param audio_format the audio format of incoming data; the + * plugin may modify the object to enforce another input + * format + */ + const struct audio_format * + (*open)(struct filter *filter, + struct audio_format *audio_format, + GError **error_r); + + /** + * Closes a filter. + */ + void (*close)(struct filter *filter); + + /** + * Filters a block of PCM data. + */ + const void *(*filter)(struct filter *filter, + const void *src, size_t src_size, + size_t *dest_buffer_r, + GError **error_r); +}; + +/** + * 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 NULL to + * ignore errors. + * @return a new filter object, or NULL on error + */ +struct filter * +filter_new(const struct filter_plugin *plugin, + const struct config_param *param, GError **error_r); + +/** + * 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 NULL to + * ignore errors. + * @return a new filter object, or NULL on error + */ +struct filter * +filter_configured_new(const struct config_param *param, GError **error_r); + +/** + * Deletes a filter. It must be closed prior to calling this + * function, see filter_close(). + * + * @param filter the filter object + */ +void +filter_free(struct filter *filter); + +/** + * Opens the filter, preparing it for filter_filter(). + * + * @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 NULL to + * ignore errors. + * @return the format of outgoing data + */ +const struct audio_format * +filter_open(struct filter *filter, struct audio_format *audio_format, + GError **error_r); + +/** + * Closes the filter. After that, you may call filter_open() again. + * + * @param filter the filter object + */ +void +filter_close(struct filter *filter); + +/** + * 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 NULL to + * ignore errors. + * @return the destination buffer on success (will be invalidated by + * filter_close() or filter_filter()), NULL on error + */ +const void * +filter_filter(struct filter *filter, const void *src, size_t src_size, + size_t *dest_size_r, + GError **error_r); + +#endif diff --git a/src/FilterRegistry.cxx b/src/FilterRegistry.cxx new file mode 100644 index 00000000..c8aff829 --- /dev/null +++ b/src/FilterRegistry.cxx @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2003-2013 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 +#include + +const struct filter_plugin *const filter_plugins[] = { + &null_filter_plugin, + &route_filter_plugin, + &normalize_filter_plugin, + &volume_filter_plugin, + &replay_gain_filter_plugin, + NULL, +}; + +const struct filter_plugin * +filter_plugin_by_name(const char *name) +{ + for (unsigned i = 0; filter_plugins[i] != NULL; ++i) + if (strcmp(filter_plugins[i]->name, name) == 0) + return filter_plugins[i]; + + return NULL; +} diff --git a/src/FilterRegistry.hxx b/src/FilterRegistry.hxx new file mode 100644 index 00000000..c21d8a59 --- /dev/null +++ b/src/FilterRegistry.hxx @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2003-2013 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 + +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; + +const struct filter_plugin * +filter_plugin_by_name(const char *name); + +#endif diff --git a/src/OutputControl.cxx b/src/OutputControl.cxx index 8e7447bc..37565082 100644 --- a/src/OutputControl.cxx +++ b/src/OutputControl.cxx @@ -30,7 +30,7 @@ extern "C" { #include "notify.hxx" #include "filter/ReplayGainFilterPlugin.hxx" -#include "filter_plugin.h" +#include "FilterPlugin.hxx" #include #include diff --git a/src/OutputFinish.cxx b/src/OutputFinish.cxx index ac6ad697..f5a1f992 100644 --- a/src/OutputFinish.cxx +++ b/src/OutputFinish.cxx @@ -23,9 +23,10 @@ extern "C" { #include "output_internal.h" #include "output_plugin.h" #include "mixer_control.h" -#include "filter_plugin.h" } +#include "FilterPlugin.hxx" + #include void diff --git a/src/OutputInit.cxx b/src/OutputInit.cxx index 6cd1e08b..5acb8c6c 100644 --- a/src/OutputInit.cxx +++ b/src/OutputInit.cxx @@ -30,14 +30,14 @@ extern "C" { #include "mixer_control.h" #include "mixer_type.h" #include "mixer_list.h" -#include "filter_plugin.h" -#include "filter_registry.h" -#include "filter/chain_filter_plugin.h" } #include "mixer/SoftwareMixerPlugin.hxx" +#include "FilterPlugin.hxx" +#include "FilterRegistry.hxx" #include "filter/AutoConvertFilterPlugin.hxx" #include "filter/ReplayGainFilterPlugin.hxx" +#include "filter/ChainFilterPlugin.hxx" #include diff --git a/src/OutputThread.cxx b/src/OutputThread.cxx index c7b01d95..e3efbcea 100644 --- a/src/OutputThread.cxx +++ b/src/OutputThread.cxx @@ -24,10 +24,10 @@ extern "C" { #include "output_internal.h" -#include "filter_plugin.h" } #include "notify.hxx" +#include "FilterPlugin.hxx" #include "filter/ConvertFilterPlugin.hxx" #include "filter/ReplayGainFilterPlugin.hxx" #include "PlayerControl.hxx" diff --git a/src/filter/AutoConvertFilterPlugin.cxx b/src/filter/AutoConvertFilterPlugin.cxx index 3a8c087b..2a183b57 100644 --- a/src/filter/AutoConvertFilterPlugin.cxx +++ b/src/filter/AutoConvertFilterPlugin.cxx @@ -20,9 +20,9 @@ #include "config.h" #include "AutoConvertFilterPlugin.hxx" #include "ConvertFilterPlugin.hxx" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" #include "audio_format.h" #include diff --git a/src/filter/ChainFilterPlugin.cxx b/src/filter/ChainFilterPlugin.cxx new file mode 100644 index 00000000..51eb4b6f --- /dev/null +++ b/src/filter/ChainFilterPlugin.cxx @@ -0,0 +1,214 @@ +/* + * Copyright (C) 2003-2013 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 "ChainFilterPlugin.hxx" +#include "conf.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" +#include "audio_format.h" + +#include + +#include + +struct ChainFilter { + /** the base class */ + struct filter base; + + GSList *children; + + ChainFilter():children(nullptr) { + filter_init(&base, &chain_filter_plugin); + } +}; + +static inline GQuark +filter_quark(void) +{ + return g_quark_from_static_string("filter"); +} + +static struct filter * +chain_filter_init(G_GNUC_UNUSED const struct config_param *param, + G_GNUC_UNUSED GError **error_r) +{ + ChainFilter *chain = new ChainFilter(); + + return &chain->base; +} + +static void +chain_free_child(gpointer data, G_GNUC_UNUSED gpointer user_data) +{ + struct filter *filter = (struct filter *)data; + + filter_free(filter); +} + +static void +chain_filter_finish(struct filter *_filter) +{ + ChainFilter *chain = (ChainFilter *)_filter; + + g_slist_foreach(chain->children, chain_free_child, NULL); + g_slist_free(chain->children); + + delete chain; +} + +/** + * Close all filters in the chain until #until is reached. #until + * itself is not closed. + */ +static void +chain_close_until(ChainFilter *chain, const struct filter *until) +{ + GSList *i = chain->children; + + while (true) { + /* this assertion fails if #until does not exist + (anymore) */ + assert(i != NULL); + + if (i->data == until) + /* don't close this filter */ + break; + + /* close this filter */ + struct filter *filter = (struct filter *)i->data; + filter_close(filter); + + i = g_slist_next(i); + } +} + +static const struct audio_format * +chain_open_child(struct filter *filter, + const struct audio_format *prev_audio_format, + GError **error_r) +{ + struct audio_format conv_audio_format = *prev_audio_format; + const struct audio_format *next_audio_format; + + next_audio_format = filter_open(filter, &conv_audio_format, error_r); + if (next_audio_format == NULL) + return NULL; + + if (!audio_format_equals(&conv_audio_format, prev_audio_format)) { + struct audio_format_string s; + + filter_close(filter); + g_set_error(error_r, filter_quark(), 0, + "Audio format not supported by filter '%s': %s", + filter->plugin->name, + audio_format_to_string(prev_audio_format, &s)); + return NULL; + } + + return next_audio_format; +} + +static const struct audio_format * +chain_filter_open(struct filter *_filter, struct audio_format *in_audio_format, + GError **error_r) +{ + ChainFilter *chain = (ChainFilter *)_filter; + const struct audio_format *audio_format = in_audio_format; + + for (GSList *i = chain->children; i != NULL; i = g_slist_next(i)) { + struct filter *filter = (struct filter *)i->data; + + audio_format = chain_open_child(filter, audio_format, error_r); + if (audio_format == NULL) { + /* rollback, close all children */ + chain_close_until(chain, filter); + return NULL; + } + } + + /* return the output format of the last filter */ + return audio_format; +} + +static void +chain_close_child(gpointer data, G_GNUC_UNUSED gpointer user_data) +{ + struct filter *filter = (struct filter *)data; + + filter_close(filter); +} + +static void +chain_filter_close(struct filter *_filter) +{ + ChainFilter *chain = (ChainFilter *)_filter; + + g_slist_foreach(chain->children, chain_close_child, NULL); +} + +static const void * +chain_filter_filter(struct filter *_filter, + const void *src, size_t src_size, + size_t *dest_size_r, GError **error_r) +{ + ChainFilter *chain = (ChainFilter *)_filter; + + for (GSList *i = chain->children; i != NULL; i = g_slist_next(i)) { + struct filter *filter = (struct filter *)i->data; + + /* feed the output of the previous filter as input + into the current one */ + src = filter_filter(filter, src, src_size, &src_size, error_r); + if (src == NULL) + return NULL; + } + + /* return the output of the last filter */ + *dest_size_r = src_size; + return src; +} + +const struct filter_plugin chain_filter_plugin = { + "chain", + chain_filter_init, + chain_filter_finish, + chain_filter_open, + chain_filter_close, + chain_filter_filter, +}; + +struct filter * +filter_chain_new(void) +{ + struct filter *filter = filter_new(&chain_filter_plugin, NULL, NULL); + /* chain_filter_init() never fails */ + assert(filter != NULL); + + return filter; +} + +void +filter_chain_append(struct filter *_chain, struct filter *filter) +{ + ChainFilter *chain = (ChainFilter *)_chain; + + chain->children = g_slist_append(chain->children, filter); +} diff --git a/src/filter/ChainFilterPlugin.hxx b/src/filter/ChainFilterPlugin.hxx new file mode 100644 index 00000000..242d29da --- /dev/null +++ b/src/filter/ChainFilterPlugin.hxx @@ -0,0 +1,48 @@ +/* + * Copyright (C) 2003-2013 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 + * + * A filter chain is a container for several filters. They are + * chained together, i.e. called in a row, one filter passing its + * output to the next one. + */ + +#ifndef MPD_FILTER_CHAIN_HXX +#define MPD_FILTER_CHAIN_HXX + +struct filter; + +/** + * Creates a new filter chain. + */ +struct filter * +filter_chain_new(void); + +/** + * Appends a new filter at the end of the filter chain. You must call + * this function before the first filter_open() call. + * + * @param chain the filter chain created with filter_chain_new() + * @param filter the filter to be appended to #chain + */ +void +filter_chain_append(struct filter *chain, struct filter *filter); + +#endif diff --git a/src/filter/ConvertFilterPlugin.cxx b/src/filter/ConvertFilterPlugin.cxx index 6a5acd70..b07cf80f 100644 --- a/src/filter/ConvertFilterPlugin.cxx +++ b/src/filter/ConvertFilterPlugin.cxx @@ -19,9 +19,9 @@ #include "config.h" #include "ConvertFilterPlugin.hxx" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" #include "conf.h" #include "PcmConvert.hxx" #include "util/Manual.hxx" diff --git a/src/filter/NormalizeFilterPlugin.cxx b/src/filter/NormalizeFilterPlugin.cxx new file mode 100644 index 00000000..0dc36c5b --- /dev/null +++ b/src/filter/NormalizeFilterPlugin.cxx @@ -0,0 +1,111 @@ +/* + * Copyright (C) 2003-2013 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 "FilterInternal.hxx" +#include "FilterRegistry.hxx" +#include "pcm_buffer.h" +#include "audio_format.h" +#include "AudioCompress/compress.h" + +#include +#include + +struct normalize_filter { + struct filter filter; + + struct Compressor *compressor; + + struct pcm_buffer buffer; +}; + +static inline GQuark +normalize_quark(void) +{ + return g_quark_from_static_string("normalize"); +} + +static struct filter * +normalize_filter_init(G_GNUC_UNUSED const struct config_param *param, + G_GNUC_UNUSED GError **error_r) +{ + struct normalize_filter *filter = g_new(struct normalize_filter, 1); + + filter_init(&filter->filter, &normalize_filter_plugin); + + return &filter->filter; +} + +static void +normalize_filter_finish(struct filter *filter) +{ + g_free(filter); +} + +static const struct audio_format * +normalize_filter_open(struct filter *_filter, + struct audio_format *audio_format, + G_GNUC_UNUSED GError **error_r) +{ + struct normalize_filter *filter = (struct normalize_filter *)_filter; + + audio_format->format = SAMPLE_FORMAT_S16; + + filter->compressor = Compressor_new(0); + + pcm_buffer_init(&filter->buffer); + + return audio_format; +} + +static void +normalize_filter_close(struct filter *_filter) +{ + struct normalize_filter *filter = (struct normalize_filter *)_filter; + + pcm_buffer_deinit(&filter->buffer); + Compressor_delete(filter->compressor); +} + +static const void * +normalize_filter_filter(struct filter *_filter, + const void *src, size_t src_size, size_t *dest_size_r, + G_GNUC_UNUSED GError **error_r) +{ + struct normalize_filter *filter = (struct normalize_filter *)_filter; + + int16_t *dest = (int16_t *)pcm_buffer_get(&filter->buffer, src_size); + + memcpy(dest, src, src_size); + + Compressor_Process_int16(filter->compressor, dest, src_size / 2); + + *dest_size_r = src_size; + return dest; +} + +const struct filter_plugin normalize_filter_plugin = { + "normalize", + normalize_filter_init, + normalize_filter_finish, + normalize_filter_open, + normalize_filter_close, + normalize_filter_filter, +}; diff --git a/src/filter/NullFilterPlugin.cxx b/src/filter/NullFilterPlugin.cxx new file mode 100644 index 00000000..9c1a9c95 --- /dev/null +++ b/src/filter/NullFilterPlugin.cxx @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2003-2013 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 filter plugin does nothing. That is not quite useful, except + * for testing the filter core, or as a template for new filter + * plugins. + */ + +#include "config.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" + +#include +#include + +struct null_filter { + struct filter filter; +}; + +static struct filter * +null_filter_init(G_GNUC_UNUSED const struct config_param *param, + G_GNUC_UNUSED GError **error_r) +{ + struct null_filter *filter = g_new(struct null_filter, 1); + + filter_init(&filter->filter, &null_filter_plugin); + return &filter->filter; +} + +static void +null_filter_finish(struct filter *_filter) +{ + struct null_filter *filter = (struct null_filter *)_filter; + + g_free(filter); +} + +static const struct audio_format * +null_filter_open(struct filter *_filter, struct audio_format *audio_format, + G_GNUC_UNUSED GError **error_r) +{ + struct null_filter *filter = (struct null_filter *)_filter; + (void)filter; + + return audio_format; +} + +static void +null_filter_close(struct filter *_filter) +{ + struct null_filter *filter = (struct null_filter *)_filter; + (void)filter; +} + +static const void * +null_filter_filter(struct filter *_filter, + const void *src, size_t src_size, + size_t *dest_size_r, G_GNUC_UNUSED GError **error_r) +{ + struct null_filter *filter = (struct null_filter *)_filter; + (void)filter; + + /* return the unmodified source buffer */ + *dest_size_r = src_size; + return src; +} + +const struct filter_plugin null_filter_plugin = { + "null", + null_filter_init, + null_filter_finish, + null_filter_open, + null_filter_close, + null_filter_filter, +}; diff --git a/src/filter/ReplayGainFilterPlugin.cxx b/src/filter/ReplayGainFilterPlugin.cxx index 9fb412be..85621353 100644 --- a/src/filter/ReplayGainFilterPlugin.cxx +++ b/src/filter/ReplayGainFilterPlugin.cxx @@ -19,9 +19,9 @@ #include "config.h" #include "ReplayGainFilterPlugin.hxx" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" #include "audio_format.h" #include "replay_gain_info.h" #include "replay_gain_config.h" diff --git a/src/filter/RouteFilterPlugin.cxx b/src/filter/RouteFilterPlugin.cxx new file mode 100644 index 00000000..35f8c5c7 --- /dev/null +++ b/src/filter/RouteFilterPlugin.cxx @@ -0,0 +1,350 @@ +/* + * Copyright (C) 2003-2013 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 filter copies audio data between channels. Useful for + * upmixing mono/stereo audio to surround speaker configurations. + * + * Its configuration consists of a "filter" section with a single + * "routes" entry, formatted as: \\ + * routes "0>1, 1>0, 2>2, 3>3, 3>4" \\ + * where each pair of numbers signifies a set of channels. + * Each source>dest pair leads to the data from channel #source + * being copied to channel #dest in the output. + * + * Example: \\ + * routes "0>0, 1>1, 0>2, 1>3"\\ + * upmixes stereo audio to a 4-speaker system, copying the front-left + * (0) to front left (0) and rear left (2), copying front-right (1) to + * front-right (1) and rear-right (3). + * + * If multiple sources are copied to the same destination channel, only + * one of them takes effect. + */ + +#include "config.h" +#include "conf.h" +#include "ConfigQuark.hxx" +#include "audio_format.h" +#include "audio_check.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" +#include "pcm_buffer.h" + +#include +#include +#include + + +struct route_filter { + + /** + * Inherit (and support cast to/from) filter + */ + struct filter base; + + /** + * The minimum number of channels we need for output + * to be able to perform all the copies the user has specified + */ + unsigned char min_output_channels; + + /** + * The minimum number of input channels we need to + * copy all the data the user has requested. If fewer + * than this many are supplied by the input, undefined + * copy operations are given zeroed sources in stead. + */ + unsigned char min_input_channels; + + /** + * The set of copy operations to perform on each sample + * The index is an output channel to use, the value is + * a corresponding input channel from which to take the + * data. A -1 means "no source" + */ + signed char* sources; + + /** + * The actual input format of our signal, once opened + */ + struct audio_format input_format; + + /** + * The decided upon output format, once opened + */ + struct audio_format output_format; + + /** + * The size, in bytes, of each multichannel frame in the + * input buffer + */ + size_t input_frame_size; + + /** + * The size, in bytes, of each multichannel frame in the + * output buffer + */ + size_t output_frame_size; + + /** + * The output buffer used last time around, can be reused if the size doesn't differ. + */ + struct pcm_buffer output_buffer; + +}; + +/** + * Parse the "routes" section, a string on the form + * 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 filter a route_filter whose min_channels and sources[] to set + * @return true on success, false on error + */ +static bool +route_filter_parse(const struct config_param *param, + struct route_filter *filter, + GError **error_r) { + + /* TODO: + * With a more clever way of marking "don't copy to output N", + * This could easily be merged into a single loop with some + * dynamic g_realloc() instead of one count run and one g_malloc(). + */ + + gchar **tokens; + int number_of_copies; + + // A cowardly default, just passthrough stereo + const char *routes = + config_get_block_string(param, "routes", "0>0, 1>1"); + + filter->min_input_channels = 0; + filter->min_output_channels = 0; + + tokens = g_strsplit(routes, ",", 255); + number_of_copies = g_strv_length(tokens); + + // Start by figuring out a few basic things about the routing set + for (int c=0; cb string into source and destination + sd = g_strsplit(tokens[c], ">", 2); + if (g_strv_length(sd) != 2) { + g_set_error(error_r, config_quark(), 1, + "Invalid copy around %d in routes spec: %s", + param->line, tokens[c]); + g_strfreev(sd); + g_strfreev(tokens); + return false; + } + + source = strtol(sd[0], NULL, 10); + dest = strtol(sd[1], NULL, 10); + + // Keep track of the highest channel numbers seen + // as either in- or outputs + if (source >= filter->min_input_channels) + filter->min_input_channels = source + 1; + if (dest >= filter->min_output_channels) + filter->min_output_channels = dest + 1; + + g_strfreev(sd); + } + + if (!audio_valid_channel_count(filter->min_output_channels)) { + g_strfreev(tokens); + g_set_error(error_r, audio_format_quark(), 0, + "Invalid number of output channels requested: %d", + filter->min_output_channels); + return false; + } + + // Allocate a map of "copy nothing to me" + filter->sources = (signed char *) + g_malloc(filter->min_output_channels * sizeof(signed char)); + + for (int i=0; imin_output_channels; ++i) + filter->sources[i] = -1; + + // Run through the spec again, and save the + // actual mapping output <- input + for (int c=0; cb string into source and destination + sd = g_strsplit(tokens[c], ">", 2); + if (g_strv_length(sd) != 2) { + g_set_error(error_r, config_quark(), 1, + "Invalid copy around %d in routes spec: %s", + param->line, tokens[c]); + g_strfreev(sd); + g_strfreev(tokens); + return false; + } + + source = strtol(sd[0], NULL, 10); + dest = strtol(sd[1], NULL, 10); + + filter->sources[dest] = source; + + g_strfreev(sd); + } + + g_strfreev(tokens); + + return true; +} + +static struct filter * +route_filter_init(const struct config_param *param, + G_GNUC_UNUSED GError **error_r) +{ + struct route_filter *filter = g_new(struct route_filter, 1); + filter_init(&filter->base, &route_filter_plugin); + + // Allocate and set the filter->sources[] array + route_filter_parse(param, filter, error_r); + + return &filter->base; +} + +static void +route_filter_finish(struct filter *_filter) +{ + struct route_filter *filter = (struct route_filter *)_filter; + + g_free(filter->sources); + g_free(filter); +} + +static const struct audio_format * +route_filter_open(struct filter *_filter, struct audio_format *audio_format, + G_GNUC_UNUSED GError **error_r) +{ + struct route_filter *filter = (struct route_filter *)_filter; + + // Copy the input format for later reference + filter->input_format = *audio_format; + filter->input_frame_size = + audio_format_frame_size(&filter->input_format); + + // Decide on an output format which has enough channels, + // and is otherwise identical + filter->output_format = *audio_format; + filter->output_format.channels = filter->min_output_channels; + + // Precalculate this simple value, to speed up allocation later + filter->output_frame_size = + audio_format_frame_size(&filter->output_format); + + // This buffer grows as needed + pcm_buffer_init(&filter->output_buffer); + + return &filter->output_format; +} + +static void +route_filter_close(struct filter *_filter) +{ + struct route_filter *filter = (struct route_filter *)_filter; + + pcm_buffer_deinit(&filter->output_buffer); +} + +static const void * +route_filter_filter(struct filter *_filter, + const void *src, size_t src_size, + size_t *dest_size_r, G_GNUC_UNUSED GError **error_r) +{ + struct route_filter *filter = (struct route_filter *)_filter; + + size_t number_of_frames = src_size / filter->input_frame_size; + + size_t bytes_per_frame_per_channel = + audio_format_sample_size(&filter->input_format); + + // A moving pointer that always refers to channel 0 in the input, at the currently handled frame + const uint8_t *base_source = (const uint8_t *)src; + + // A moving pointer that always refers to the currently filled channel of the currently handled frame, in the output + uint8_t *chan_destination; + + // Grow our reusable buffer, if needed, and set the moving pointer + *dest_size_r = number_of_frames * filter->output_frame_size; + chan_destination = (uint8_t *) + pcm_buffer_get(&filter->output_buffer, *dest_size_r); + + + // Perform our copy operations, with N input channels and M output channels + for (unsigned int s=0; smin_output_channels; ++c) { + if (filter->sources[c] == -1 || + (unsigned)filter->sources[c] >= filter->input_format.channels) { + // No source for this destination output, + // give it zeroes as input + memset(chan_destination, + 0x00, + bytes_per_frame_per_channel); + } else { + // Get the data from channel sources[c] + // and copy it to the output + const uint8_t *data = base_source + + (filter->sources[c] * bytes_per_frame_per_channel); + memcpy(chan_destination, + data, + bytes_per_frame_per_channel); + } + // Move on to the next output channel + chan_destination += bytes_per_frame_per_channel; + } + + + // Go on to the next N input samples + base_source += filter->input_frame_size; + } + + // Here it is, ladies and gentlemen! Rerouted data! + return (void *) filter->output_buffer.buffer; +} + +const struct filter_plugin route_filter_plugin = { + "route", + route_filter_init, + route_filter_finish, + route_filter_open, + route_filter_close, + route_filter_filter, +}; diff --git a/src/filter/VolumeFilterPlugin.cxx b/src/filter/VolumeFilterPlugin.cxx index 5066ebbf..f1a1f478 100644 --- a/src/filter/VolumeFilterPlugin.cxx +++ b/src/filter/VolumeFilterPlugin.cxx @@ -19,9 +19,9 @@ #include "config.h" #include "VolumeFilterPlugin.hxx" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" +#include "FilterPlugin.hxx" +#include "FilterInternal.hxx" +#include "FilterRegistry.hxx" #include "conf.h" #include "pcm_buffer.h" #include "PcmVolume.hxx" diff --git a/src/filter/chain_filter_plugin.c b/src/filter/chain_filter_plugin.c deleted file mode 100644 index 0788b675..00000000 --- a/src/filter/chain_filter_plugin.c +++ /dev/null @@ -1,215 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 "conf.h" -#include "filter/chain_filter_plugin.h" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" -#include "audio_format.h" - -#include - -#include - -struct filter_chain { - /** the base class */ - struct filter base; - - GSList *children; -}; - -static inline GQuark -filter_quark(void) -{ - return g_quark_from_static_string("filter"); -} - -static struct filter * -chain_filter_init(G_GNUC_UNUSED const struct config_param *param, - G_GNUC_UNUSED GError **error_r) -{ - struct filter_chain *chain = g_new(struct filter_chain, 1); - - filter_init(&chain->base, &chain_filter_plugin); - chain->children = NULL; - - return &chain->base; -} - -static void -chain_free_child(gpointer data, G_GNUC_UNUSED gpointer user_data) -{ - struct filter *filter = data; - - filter_free(filter); -} - -static void -chain_filter_finish(struct filter *_filter) -{ - struct filter_chain *chain = (struct filter_chain *)_filter; - - g_slist_foreach(chain->children, chain_free_child, NULL); - g_slist_free(chain->children); - - g_free(chain); -} - -/** - * Close all filters in the chain until #until is reached. #until - * itself is not closed. - */ -static void -chain_close_until(struct filter_chain *chain, const struct filter *until) -{ - GSList *i = chain->children; - struct filter *filter; - - while (true) { - /* this assertion fails if #until does not exist - (anymore) */ - assert(i != NULL); - - if (i->data == until) - /* don't close this filter */ - break; - - /* close this filter */ - filter = i->data; - filter_close(filter); - - i = g_slist_next(i); - } -} - -static const struct audio_format * -chain_open_child(struct filter *filter, - const struct audio_format *prev_audio_format, - GError **error_r) -{ - struct audio_format conv_audio_format = *prev_audio_format; - const struct audio_format *next_audio_format; - - next_audio_format = filter_open(filter, &conv_audio_format, error_r); - if (next_audio_format == NULL) - return NULL; - - if (!audio_format_equals(&conv_audio_format, prev_audio_format)) { - struct audio_format_string s; - - filter_close(filter); - g_set_error(error_r, filter_quark(), 0, - "Audio format not supported by filter '%s': %s", - filter->plugin->name, - audio_format_to_string(prev_audio_format, &s)); - return NULL; - } - - return next_audio_format; -} - -static const struct audio_format * -chain_filter_open(struct filter *_filter, struct audio_format *in_audio_format, - GError **error_r) -{ - struct filter_chain *chain = (struct filter_chain *)_filter; - const struct audio_format *audio_format = in_audio_format; - - for (GSList *i = chain->children; i != NULL; i = g_slist_next(i)) { - struct filter *filter = i->data; - - audio_format = chain_open_child(filter, audio_format, error_r); - if (audio_format == NULL) { - /* rollback, close all children */ - chain_close_until(chain, filter); - return NULL; - } - } - - /* return the output format of the last filter */ - return audio_format; -} - -static void -chain_close_child(gpointer data, G_GNUC_UNUSED gpointer user_data) -{ - struct filter *filter = data; - - filter_close(filter); -} - -static void -chain_filter_close(struct filter *_filter) -{ - struct filter_chain *chain = (struct filter_chain *)_filter; - - g_slist_foreach(chain->children, chain_close_child, NULL); -} - -static const void * -chain_filter_filter(struct filter *_filter, - const void *src, size_t src_size, - size_t *dest_size_r, GError **error_r) -{ - struct filter_chain *chain = (struct filter_chain *)_filter; - - for (GSList *i = chain->children; i != NULL; i = g_slist_next(i)) { - struct filter *filter = i->data; - - /* feed the output of the previous filter as input - into the current one */ - src = filter_filter(filter, src, src_size, &src_size, error_r); - if (src == NULL) - return NULL; - } - - /* return the output of the last filter */ - *dest_size_r = src_size; - return src; -} - -const struct filter_plugin chain_filter_plugin = { - .name = "chain", - .init = chain_filter_init, - .finish = chain_filter_finish, - .open = chain_filter_open, - .close = chain_filter_close, - .filter = chain_filter_filter, -}; - -struct filter * -filter_chain_new(void) -{ - struct filter *filter = filter_new(&chain_filter_plugin, NULL, NULL); - /* chain_filter_init() never fails */ - assert(filter != NULL); - - return filter; -} - -void -filter_chain_append(struct filter *_chain, struct filter *filter) -{ - struct filter_chain *chain = (struct filter_chain *)_chain; - - chain->children = g_slist_append(chain->children, filter); -} - diff --git a/src/filter/chain_filter_plugin.h b/src/filter/chain_filter_plugin.h deleted file mode 100644 index 1dba4666..00000000 --- a/src/filter/chain_filter_plugin.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 - * - * A filter chain is a container for several filters. They are - * chained together, i.e. called in a row, one filter passing its - * output to the next one. - */ - -#ifndef MPD_FILTER_CHAIN_H -#define MPD_FILTER_CHAIN_H - -struct filter; - -/** - * Creates a new filter chain. - */ -struct filter * -filter_chain_new(void); - -/** - * Appends a new filter at the end of the filter chain. You must call - * this function before the first filter_open() call. - * - * @param chain the filter chain created with filter_chain_new() - * @param filter the filter to be appended to #chain - */ -void -filter_chain_append(struct filter *chain, struct filter *filter); - -#endif diff --git a/src/filter/normalize_filter_plugin.c b/src/filter/normalize_filter_plugin.c deleted file mode 100644 index 2151482e..00000000 --- a/src/filter/normalize_filter_plugin.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" -#include "pcm_buffer.h" -#include "audio_format.h" -#include "AudioCompress/compress.h" - -#include -#include - -struct normalize_filter { - struct filter filter; - - struct Compressor *compressor; - - struct pcm_buffer buffer; -}; - -static inline GQuark -normalize_quark(void) -{ - return g_quark_from_static_string("normalize"); -} - -static struct filter * -normalize_filter_init(G_GNUC_UNUSED const struct config_param *param, - G_GNUC_UNUSED GError **error_r) -{ - struct normalize_filter *filter = g_new(struct normalize_filter, 1); - - filter_init(&filter->filter, &normalize_filter_plugin); - - return &filter->filter; -} - -static void -normalize_filter_finish(struct filter *filter) -{ - g_free(filter); -} - -static const struct audio_format * -normalize_filter_open(struct filter *_filter, - struct audio_format *audio_format, - G_GNUC_UNUSED GError **error_r) -{ - struct normalize_filter *filter = (struct normalize_filter *)_filter; - - audio_format->format = SAMPLE_FORMAT_S16; - - filter->compressor = Compressor_new(0); - - pcm_buffer_init(&filter->buffer); - - return audio_format; -} - -static void -normalize_filter_close(struct filter *_filter) -{ - struct normalize_filter *filter = (struct normalize_filter *)_filter; - - pcm_buffer_deinit(&filter->buffer); - Compressor_delete(filter->compressor); -} - -static const void * -normalize_filter_filter(struct filter *_filter, - const void *src, size_t src_size, size_t *dest_size_r, - G_GNUC_UNUSED GError **error_r) -{ - struct normalize_filter *filter = (struct normalize_filter *)_filter; - void *dest; - - dest = pcm_buffer_get(&filter->buffer, src_size); - - memcpy(dest, src, src_size); - - Compressor_Process_int16(filter->compressor, dest, src_size / 2); - - *dest_size_r = src_size; - return dest; -} - -const struct filter_plugin normalize_filter_plugin = { - .name = "normalize", - .init = normalize_filter_init, - .finish = normalize_filter_finish, - .open = normalize_filter_open, - .close = normalize_filter_close, - .filter = normalize_filter_filter, -}; diff --git a/src/filter/null_filter_plugin.c b/src/filter/null_filter_plugin.c deleted file mode 100644 index 7728c55b..00000000 --- a/src/filter/null_filter_plugin.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 filter plugin does nothing. That is not quite useful, except - * for testing the filter core, or as a template for new filter - * plugins. - */ - -#include "config.h" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" - -#include -#include - -struct null_filter { - struct filter filter; -}; - -static struct filter * -null_filter_init(G_GNUC_UNUSED const struct config_param *param, - G_GNUC_UNUSED GError **error_r) -{ - struct null_filter *filter = g_new(struct null_filter, 1); - - filter_init(&filter->filter, &null_filter_plugin); - return &filter->filter; -} - -static void -null_filter_finish(struct filter *_filter) -{ - struct null_filter *filter = (struct null_filter *)_filter; - - g_free(filter); -} - -static const struct audio_format * -null_filter_open(struct filter *_filter, struct audio_format *audio_format, - G_GNUC_UNUSED GError **error_r) -{ - struct null_filter *filter = (struct null_filter *)_filter; - (void)filter; - - return audio_format; -} - -static void -null_filter_close(struct filter *_filter) -{ - struct null_filter *filter = (struct null_filter *)_filter; - (void)filter; -} - -static const void * -null_filter_filter(struct filter *_filter, - const void *src, size_t src_size, - size_t *dest_size_r, G_GNUC_UNUSED GError **error_r) -{ - struct null_filter *filter = (struct null_filter *)_filter; - (void)filter; - - /* return the unmodified source buffer */ - *dest_size_r = src_size; - return src; -} - -const struct filter_plugin null_filter_plugin = { - .name = "null", - .init = null_filter_init, - .finish = null_filter_finish, - .open = null_filter_open, - .close = null_filter_close, - .filter = null_filter_filter, -}; diff --git a/src/filter/route_filter_plugin.c b/src/filter/route_filter_plugin.c deleted file mode 100644 index c0ecbd9c..00000000 --- a/src/filter/route_filter_plugin.c +++ /dev/null @@ -1,349 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 filter copies audio data between channels. Useful for - * upmixing mono/stereo audio to surround speaker configurations. - * - * Its configuration consists of a "filter" section with a single - * "routes" entry, formatted as: \\ - * routes "0>1, 1>0, 2>2, 3>3, 3>4" \\ - * where each pair of numbers signifies a set of channels. - * Each source>dest pair leads to the data from channel #source - * being copied to channel #dest in the output. - * - * Example: \\ - * routes "0>0, 1>1, 0>2, 1>3"\\ - * upmixes stereo audio to a 4-speaker system, copying the front-left - * (0) to front left (0) and rear left (2), copying front-right (1) to - * front-right (1) and rear-right (3). - * - * If multiple sources are copied to the same destination channel, only - * one of them takes effect. - */ - -#include "config.h" -#include "conf.h" -#include "ConfigQuark.hxx" -#include "audio_format.h" -#include "audio_check.h" -#include "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" -#include "pcm_buffer.h" - -#include -#include -#include - - -struct route_filter { - - /** - * Inherit (and support cast to/from) filter - */ - struct filter base; - - /** - * The minimum number of channels we need for output - * to be able to perform all the copies the user has specified - */ - unsigned char min_output_channels; - - /** - * The minimum number of input channels we need to - * copy all the data the user has requested. If fewer - * than this many are supplied by the input, undefined - * copy operations are given zeroed sources in stead. - */ - unsigned char min_input_channels; - - /** - * The set of copy operations to perform on each sample - * The index is an output channel to use, the value is - * a corresponding input channel from which to take the - * data. A -1 means "no source" - */ - signed char* sources; - - /** - * The actual input format of our signal, once opened - */ - struct audio_format input_format; - - /** - * The decided upon output format, once opened - */ - struct audio_format output_format; - - /** - * The size, in bytes, of each multichannel frame in the - * input buffer - */ - size_t input_frame_size; - - /** - * The size, in bytes, of each multichannel frame in the - * output buffer - */ - size_t output_frame_size; - - /** - * The output buffer used last time around, can be reused if the size doesn't differ. - */ - struct pcm_buffer output_buffer; - -}; - -/** - * Parse the "routes" section, a string on the form - * 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 filter a route_filter whose min_channels and sources[] to set - * @return true on success, false on error - */ -static bool -route_filter_parse(const struct config_param *param, - struct route_filter *filter, - GError **error_r) { - - /* TODO: - * With a more clever way of marking "don't copy to output N", - * This could easily be merged into a single loop with some - * dynamic g_realloc() instead of one count run and one g_malloc(). - */ - - gchar **tokens; - int number_of_copies; - - // A cowardly default, just passthrough stereo - const char *routes = - config_get_block_string(param, "routes", "0>0, 1>1"); - - filter->min_input_channels = 0; - filter->min_output_channels = 0; - - tokens = g_strsplit(routes, ",", 255); - number_of_copies = g_strv_length(tokens); - - // Start by figuring out a few basic things about the routing set - for (int c=0; cb string into source and destination - sd = g_strsplit(tokens[c], ">", 2); - if (g_strv_length(sd) != 2) { - g_set_error(error_r, config_quark(), 1, - "Invalid copy around %d in routes spec: %s", - param->line, tokens[c]); - g_strfreev(sd); - g_strfreev(tokens); - return false; - } - - source = strtol(sd[0], NULL, 10); - dest = strtol(sd[1], NULL, 10); - - // Keep track of the highest channel numbers seen - // as either in- or outputs - if (source >= filter->min_input_channels) - filter->min_input_channels = source + 1; - if (dest >= filter->min_output_channels) - filter->min_output_channels = dest + 1; - - g_strfreev(sd); - } - - if (!audio_valid_channel_count(filter->min_output_channels)) { - g_strfreev(tokens); - g_set_error(error_r, audio_format_quark(), 0, - "Invalid number of output channels requested: %d", - filter->min_output_channels); - return false; - } - - // Allocate a map of "copy nothing to me" - filter->sources = - g_malloc(filter->min_output_channels * sizeof(signed char)); - - for (int i=0; imin_output_channels; ++i) - filter->sources[i] = -1; - - // Run through the spec again, and save the - // actual mapping output <- input - for (int c=0; cb string into source and destination - sd = g_strsplit(tokens[c], ">", 2); - if (g_strv_length(sd) != 2) { - g_set_error(error_r, config_quark(), 1, - "Invalid copy around %d in routes spec: %s", - param->line, tokens[c]); - g_strfreev(sd); - g_strfreev(tokens); - return false; - } - - source = strtol(sd[0], NULL, 10); - dest = strtol(sd[1], NULL, 10); - - filter->sources[dest] = source; - - g_strfreev(sd); - } - - g_strfreev(tokens); - - return true; -} - -static struct filter * -route_filter_init(const struct config_param *param, - G_GNUC_UNUSED GError **error_r) -{ - struct route_filter *filter = g_new(struct route_filter, 1); - filter_init(&filter->base, &route_filter_plugin); - - // Allocate and set the filter->sources[] array - route_filter_parse(param, filter, error_r); - - return &filter->base; -} - -static void -route_filter_finish(struct filter *_filter) -{ - struct route_filter *filter = (struct route_filter *)_filter; - - g_free(filter->sources); - g_free(filter); -} - -static const struct audio_format * -route_filter_open(struct filter *_filter, struct audio_format *audio_format, - G_GNUC_UNUSED GError **error_r) -{ - struct route_filter *filter = (struct route_filter *)_filter; - - // Copy the input format for later reference - filter->input_format = *audio_format; - filter->input_frame_size = - audio_format_frame_size(&filter->input_format); - - // Decide on an output format which has enough channels, - // and is otherwise identical - filter->output_format = *audio_format; - filter->output_format.channels = filter->min_output_channels; - - // Precalculate this simple value, to speed up allocation later - filter->output_frame_size = - audio_format_frame_size(&filter->output_format); - - // This buffer grows as needed - pcm_buffer_init(&filter->output_buffer); - - return &filter->output_format; -} - -static void -route_filter_close(struct filter *_filter) -{ - struct route_filter *filter = (struct route_filter *)_filter; - - pcm_buffer_deinit(&filter->output_buffer); -} - -static const void * -route_filter_filter(struct filter *_filter, - const void *src, size_t src_size, - size_t *dest_size_r, G_GNUC_UNUSED GError **error_r) -{ - struct route_filter *filter = (struct route_filter *)_filter; - - size_t number_of_frames = src_size / filter->input_frame_size; - - size_t bytes_per_frame_per_channel = - audio_format_sample_size(&filter->input_format); - - // A moving pointer that always refers to channel 0 in the input, at the currently handled frame - const uint8_t *base_source = src; - - // A moving pointer that always refers to the currently filled channel of the currently handled frame, in the output - uint8_t *chan_destination; - - // Grow our reusable buffer, if needed, and set the moving pointer - *dest_size_r = number_of_frames * filter->output_frame_size; - chan_destination = pcm_buffer_get(&filter->output_buffer, *dest_size_r); - - - // Perform our copy operations, with N input channels and M output channels - for (unsigned int s=0; smin_output_channels; ++c) { - if (filter->sources[c] == -1 || - (unsigned)filter->sources[c] >= filter->input_format.channels) { - // No source for this destination output, - // give it zeroes as input - memset(chan_destination, - 0x00, - bytes_per_frame_per_channel); - } else { - // Get the data from channel sources[c] - // and copy it to the output - const uint8_t *data = base_source + - (filter->sources[c] * bytes_per_frame_per_channel); - memcpy(chan_destination, - data, - bytes_per_frame_per_channel); - } - // Move on to the next output channel - chan_destination += bytes_per_frame_per_channel; - } - - - // Go on to the next N input samples - base_source += filter->input_frame_size; - } - - // Here it is, ladies and gentlemen! Rerouted data! - return (void *) filter->output_buffer.buffer; -} - -const struct filter_plugin route_filter_plugin = { - .name = "route", - .init = route_filter_init, - .finish = route_filter_finish, - .open = route_filter_open, - .close = route_filter_close, - .filter = route_filter_filter, -}; diff --git a/src/filter_internal.h b/src/filter_internal.h deleted file mode 100644 index 4e94599a..00000000 --- a/src/filter_internal.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2003-2011 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_H -#define MPD_FILTER_INTERNAL_H - -struct filter { - const struct filter_plugin *plugin; -}; - -static inline void -filter_init(struct filter *filter, const struct filter_plugin *plugin) -{ - filter->plugin = plugin; -} - -#endif diff --git a/src/filter_plugin.c b/src/filter_plugin.c deleted file mode 100644 index 2e3c8fec..00000000 --- a/src/filter_plugin.c +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 "filter_plugin.h" -#include "filter_internal.h" -#include "filter_registry.h" -#include "conf.h" -#include "ConfigQuark.hxx" - -#ifndef NDEBUG -#include "audio_format.h" -#endif - -#include - -struct filter * -filter_new(const struct filter_plugin *plugin, - const struct config_param *param, GError **error_r) -{ - assert(plugin != NULL); - assert(error_r == NULL || *error_r == NULL); - - return plugin->init(param, error_r); -} - -struct filter * -filter_configured_new(const struct config_param *param, GError **error_r) -{ - const char *plugin_name; - const struct filter_plugin *plugin; - - assert(param != NULL); - assert(error_r == NULL || *error_r == NULL); - - plugin_name = config_get_block_string(param, "plugin", NULL); - if (plugin_name == NULL) { - g_set_error(error_r, config_quark(), 0, - "No filter plugin specified"); - return NULL; - } - - plugin = filter_plugin_by_name(plugin_name); - if (plugin == NULL) { - g_set_error(error_r, config_quark(), 0, - "No such filter plugin: %s", plugin_name); - return NULL; - } - - return filter_new(plugin, param, error_r); -} - -void -filter_free(struct filter *filter) -{ - assert(filter != NULL); - - filter->plugin->finish(filter); -} - -const struct audio_format * -filter_open(struct filter *filter, struct audio_format *audio_format, - GError **error_r) -{ - const struct audio_format *out_audio_format; - - assert(filter != NULL); - assert(audio_format != NULL); - assert(audio_format_valid(audio_format)); - assert(error_r == NULL || *error_r == NULL); - - out_audio_format = filter->plugin->open(filter, audio_format, error_r); - - assert(out_audio_format == NULL || audio_format_valid(audio_format)); - assert(out_audio_format == NULL || - audio_format_valid(out_audio_format)); - - return out_audio_format; -} - -void -filter_close(struct filter *filter) -{ - assert(filter != NULL); - - filter->plugin->close(filter); -} - -const void * -filter_filter(struct filter *filter, const void *src, size_t src_size, - size_t *dest_size_r, - GError **error_r) -{ - assert(filter != NULL); - assert(src != NULL); - assert(src_size > 0); - assert(dest_size_r != NULL); - assert(error_r == NULL || *error_r == NULL); - - return filter->plugin->filter(filter, src, src_size, dest_size_r, error_r); -} diff --git a/src/filter_plugin.h b/src/filter_plugin.h deleted file mode 100644 index ae14a245..00000000 --- a/src/filter_plugin.h +++ /dev/null @@ -1,158 +0,0 @@ -/* - * Copyright (C) 2003-2011 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_H -#define MPD_FILTER_PLUGIN_H - -#include "gerror.h" - -#include -#include - -struct config_param; -struct filter; - -struct filter_plugin { - const char *name; - - /** - * Allocates and configures a filter. - */ - struct filter *(*init)(const struct config_param *param, - GError **error_r); - - /** - * Free instance data. - */ - void (*finish)(struct filter *filter); - - /** - * Opens a filter. - * - * @param audio_format the audio format of incoming data; the - * plugin may modify the object to enforce another input - * format - */ - const struct audio_format * - (*open)(struct filter *filter, - struct audio_format *audio_format, - GError **error_r); - - /** - * Closes a filter. - */ - void (*close)(struct filter *filter); - - /** - * Filters a block of PCM data. - */ - const void *(*filter)(struct filter *filter, - const void *src, size_t src_size, - size_t *dest_buffer_r, - GError **error_r); -}; - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * 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 NULL to - * ignore errors. - * @return a new filter object, or NULL on error - */ -struct filter * -filter_new(const struct filter_plugin *plugin, - const struct config_param *param, GError **error_r); - -/** - * 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 NULL to - * ignore errors. - * @return a new filter object, or NULL on error - */ -struct filter * -filter_configured_new(const struct config_param *param, GError **error_r); - -/** - * Deletes a filter. It must be closed prior to calling this - * function, see filter_close(). - * - * @param filter the filter object - */ -void -filter_free(struct filter *filter); - -/** - * Opens the filter, preparing it for filter_filter(). - * - * @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 NULL to - * ignore errors. - * @return the format of outgoing data - */ -const struct audio_format * -filter_open(struct filter *filter, struct audio_format *audio_format, - GError **error_r); - -/** - * Closes the filter. After that, you may call filter_open() again. - * - * @param filter the filter object - */ -void -filter_close(struct filter *filter); - -/** - * 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 NULL to - * ignore errors. - * @return the destination buffer on success (will be invalidated by - * filter_close() or filter_filter()), NULL on error - */ -const void * -filter_filter(struct filter *filter, const void *src, size_t src_size, - size_t *dest_size_r, - GError **error_r); - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/src/filter_registry.c b/src/filter_registry.c deleted file mode 100644 index dc188939..00000000 --- a/src/filter_registry.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2003-2011 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 "filter_registry.h" -#include "filter_plugin.h" - -#include -#include - -const struct filter_plugin *const filter_plugins[] = { - &null_filter_plugin, - &route_filter_plugin, - &normalize_filter_plugin, - &volume_filter_plugin, - &replay_gain_filter_plugin, - NULL, -}; - -const struct filter_plugin * -filter_plugin_by_name(const char *name) -{ - for (unsigned i = 0; filter_plugins[i] != NULL; ++i) - if (strcmp(filter_plugins[i]->name, name) == 0) - return filter_plugins[i]; - - return NULL; -} diff --git a/src/filter_registry.h b/src/filter_registry.h deleted file mode 100644 index d3949c7c..00000000 --- a/src/filter_registry.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2003-2011 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_H -#define MPD_FILTER_REGISTRY_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; - -const struct filter_plugin * -filter_plugin_by_name(const char *name); - -#endif diff --git a/src/mixer/SoftwareMixerPlugin.cxx b/src/mixer/SoftwareMixerPlugin.cxx index c06ce18e..9b8f083f 100644 --- a/src/mixer/SoftwareMixerPlugin.cxx +++ b/src/mixer/SoftwareMixerPlugin.cxx @@ -20,8 +20,8 @@ #include "config.h" #include "SoftwareMixerPlugin.hxx" #include "mixer_api.h" -#include "filter_plugin.h" -#include "filter_registry.h" +#include "FilterPlugin.hxx" +#include "FilterRegistry.hxx" #include "filter/VolumeFilterPlugin.hxx" #include "PcmVolume.hxx" diff --git a/test/read_mixer.cxx b/test/read_mixer.cxx index d0426c9a..5cd9b2c5 100644 --- a/test/read_mixer.cxx +++ b/test/read_mixer.cxx @@ -22,9 +22,9 @@ extern "C" { #include "mixer_control.h" #include "mixer_list.h" -#include "filter_registry.h" } +#include "FilterRegistry.hxx" #include "PcmVolume.hxx" #include "GlobalEvents.hxx" #include "Main.hxx" diff --git a/test/run_filter.cxx b/test/run_filter.cxx index 2d53ed49..1800996c 100644 --- a/test/run_filter.cxx +++ b/test/run_filter.cxx @@ -22,7 +22,7 @@ #include "fs/Path.hxx" #include "AudioParser.hxx" #include "audio_format.h" -#include "filter_plugin.h" +#include "FilterPlugin.hxx" #include "PcmVolume.hxx" #include "mixer_control.h" #include "stdbin.h" diff --git a/test/run_output.cxx b/test/run_output.cxx index f76e6fc7..5b6d54a1 100644 --- a/test/run_output.cxx +++ b/test/run_output.cxx @@ -32,9 +32,9 @@ extern "C" { #include "output_plugin.h" #include "output_internal.h" -#include "filter_registry.h" } +#include "FilterRegistry.hxx" #include "PlayerControl.hxx" #include "stdbin.h" -- cgit v1.2.3