Index: plugins/universal/Makefile
===================================================================
--- plugins/universal/Makefile	(revision 5985)
+++ plugins/universal/Makefile	(revision 5986)
@@ -6,5 +6,5 @@
 TARGETS_IO=piface
 TARGETS_SERVICE=service-about
-TARGETS_SLFI=filter-slfi-helloworld filter-slfi-chain
+TARGETS_SLFI=filter-slfi-helloworld filter-slfi-chain filter-slfi-alternative
 TARGETS__NAMES=$(TARGETS_MISC) $(TARGETS_PROTO) $(TARGETS_SERVICE) $(TARGETS_IO) $(TARGETS_SLFI)
 TARGETS       = $(foreach c,$(TARGETS__NAMES),$c$(SHARED_SUFFIX))
Index: plugins/universal/filter-slfi-alternative.c
===================================================================
--- plugins/universal/filter-slfi-alternative.c	(revision 5986)
+++ plugins/universal/filter-slfi-alternative.c	(revision 5986)
@@ -0,0 +1,169 @@
+//filter-slfi-alternative.c:
+
+/*
+ *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2014
+ *
+ *  This file is part of roard a part of RoarAudio,
+ *  a cross-platform sound system for both, home and professional use.
+ *  See README for details.
+ *
+ *  This file is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License version 3
+ *  as published by the Free Software Foundation.
+ *
+ *  RoarAudio 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 software; see the file COPYING.  If not, write to
+ *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+ *  Boston, MA 02110-1301, USA.
+ *
+ */
+
+#include <roaraudio.h>
+#include <libroarlight/libroarlight.h>
+
+#define MAX_FILTER  32
+
+struct slfi_alternative {
+ struct roar_slfi_inst * filter[MAX_FILTER];
+ size_t filter_len;
+ size_t current;
+ ssize_t channel;
+ uint8_t event;
+};
+
+static int __cb_event_add(struct roar_slfi_inst * inst, void * userdata, uint8_t event) {
+ (void)inst;
+ return roar_slfi_event_add(userdata, event);
+}
+
+static int __init(struct roar_slfi_inst * inst, const struct roar_keyval * para, ssize_t paralen) {
+ struct slfi_alternative * self = roar_mm_malloc(sizeof(struct slfi_alternative));
+
+ (void)para, (void)paralen;
+
+ if ( self == NULL )
+  return -1;
+
+ self->filter_len =  0;
+ self->current    =  0;
+ self->channel    = -1;
+ self->event      = ROAR_ROARDMX_EVENT_STEP;
+ inst->userdata = self;
+
+ return 0;
+}
+
+static int __uninit(struct roar_slfi_inst * inst) {
+ struct slfi_alternative * self = inst->userdata;
+ size_t i;
+
+ for (i = 0; i < self->filter_len; i++) {
+  roar_slfi_unref(self->filter[i]);
+ }
+
+ return 0;
+}
+
+static int __update(struct roar_slfi_inst * inst, uint8_t * universe, ssize_t size_of_universe, int32_t usecspassed, const uint8_t * event, size_t eventlen) {
+ struct slfi_alternative * self = inst->userdata;
+ size_t i;
+
+ // Don't do anything if we have no childs:
+ if ( self->filter_len == 0 )
+  return 0;
+
+ if ( self->channel == (ssize_t)-1 ) {
+  for (i = 0; i < eventlen; i++) {
+   if ( event[i] == self->event ) {
+    self->current++;
+    if ( self->current == self->filter_len )
+     self->current = 0;
+    break;
+   }
+  }
+ } else if ( size_of_universe > self->channel ) {
+  self->current = universe[self->channel] / self->filter_len;
+  if ( self->current >= self->filter_len )
+   self->current = self->filter_len - 1;
+ } else {
+  ROAR_WARN("__update(*): Universe too small for filter (source channel=%lu).", (unsigned long int)self->channel);
+  roar_err_set(ROAR_ERROR_NOENT);
+  return -1;
+ }
+
+ return roar_slfi_update(self->filter[self->current], universe, size_of_universe, usecspassed, event, eventlen);
+}
+
+static int __ctl(struct roar_slfi_inst * inst, enum roar_slfi_command command, void * argp) {
+ struct slfi_alternative * self = inst->userdata;
+
+ switch (command) {
+  case ROAR_SLFI_CMD_PUSH:
+    if ( self->filter_len == MAX_FILTER ) {
+     roar_err_set(ROAR_ERROR_NOSPC);
+     return -1;
+    }
+    if ( roar_slfi_ref(argp) == -1 )
+     return -1;
+    roar_slfi_cb_set_event_add(argp, __cb_event_add, inst);
+    self->filter[self->filter_len++] = argp;
+    return 0;
+   break;
+#ifndef DEBUG
+  default:
+   break;
+#endif
+ }
+
+ roar_err_set(ROAR_ERROR_BADRQC);
+ return -1;
+}
+
+static const struct roar_slfi_filter filter[1] = {
+ {
+  .name = "chain",
+  .description = "Chain SLFI filter",
+  .flags = ROAR_SLFI_FLAG_NONE,
+  .init = __init,
+  .uninit = __uninit,
+  .update = __update,
+  .ctl = __ctl
+ }
+};
+
+ROAR_DL_PLUGIN_REG_SLFI(filter);
+
+// This is the plugin control block.
+ROAR_DL_PLUGIN_START(filter_slfi_alternative) {
+ // Here we set the name and vendor of our plugin.
+ // If you have no Vendor ID you need to use ROAR_DL_PLUGIN_META_PRODUCT_NV().
+ ROAR_DL_PLUGIN_META_PRODUCT_NIV("filter-slfi-alternative", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO);
+
+ // This sets the version of your plugin.
+ ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING);
+
+ // This sets the license of your plugin.
+ // If there is no tag for the license you use you can just
+ // use ROAR_DL_PLUGIN_META_LICENSE().
+ ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0);
+
+ // This sets the author and contact infos.
+ // There are several other macros to do this with other parameters.
+ // See ROAR_DL_PLUGIN_META_CONTACT*() in the header or documentation.
+ ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org");
+
+ // This sets the description for your plugin.
+ ROAR_DL_PLUGIN_META_DESC("This is a container plugin for SLFI filter alternatives.");
+
+ // Load filters.
+ ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_FILTER);
+
+// This is the end of the control block.
+} ROAR_DL_PLUGIN_END
+
+//ll
