//filter-slfi-channel2event.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2015 * * 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 #include #define FLAG_BLACKOUT 0x0001 #define FLAG_FULLON 0x0002 struct slfi_channel2event { ssize_t channel; uint8_t lastvalue; uint8_t event; int flags; int emitting; }; static int __str2bool(const char * str) { if ( *str == 'y' || *str == 'j' || *str == '1' || *str == 't' ) return 1; return 0; } static int __init(struct roar_slfi_inst * inst, const struct roar_keyval * para, ssize_t paralen) { struct slfi_channel2event * self = roar_mm_malloc(sizeof(struct slfi_channel2event)); const struct roar_keyval * kv; ssize_t i; if ( self == NULL ) return -1; self->channel = -1; self->lastvalue = 0; self->event = ROAR_ROARDMX_EVENT_STEP; self->flags = FLAG_BLACKOUT|FLAG_FULLON; self->emitting = 0; inst->userdata = self; for (i = 0; i < paralen; i++) { kv = &(para[i]); if ( kv->key == NULL || kv->value == NULL ) continue; if ( !strcmp(kv->key, "channel") ) { self->channel = atoi(kv->value); if ( self->channel < 0 ) self->channel = 0; } else if ( !strcmp(kv->key, "event") ) { self->event = roar_roardmx_str2event(kv->value); } else if ( !strcmp(kv->key, "blackout") ) { self->flags |= FLAG_BLACKOUT; if ( !__str2bool(kv->value) ) self->flags -= FLAG_BLACKOUT; } else if ( !strcmp(kv->key, "fullon") ) { self->flags |= FLAG_BLACKOUT; if ( !__str2bool(kv->value) ) self->flags -= FLAG_BLACKOUT; } else { ROAR_WARN("__init(*): Unknown parameter: %s", kv->key); } } 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_channel2event * self = inst->userdata; register uint8_t value; (void)usecspassed, (void)event, (void)eventlen; if ( self->channel >= size_of_universe ) { ROAR_WARN("__update(*): Universe too small for filter (source channel=%lu).", (unsigned long int)self->channel); roar_err_set(ROAR_ERROR_INVAL); return -1; } value = universe[self->channel]; if ( (self->flags & FLAG_BLACKOUT) && value == 0x00 ) { if ( self->emitting & FLAG_FULLON ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_OFF); self->emitting -= FLAG_FULLON; } if ( !(self->emitting & FLAG_BLACKOUT) ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_ON); self->emitting |= FLAG_BLACKOUT; } } else if ( (self->flags & FLAG_FULLON) && value == 0xFF ) { if ( self->emitting & FLAG_BLACKOUT ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_OFF); self->emitting -= FLAG_BLACKOUT; } if ( !(self->emitting & FLAG_FULLON) ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_ON); self->emitting |= FLAG_FULLON; } } else { if ( self->emitting & FLAG_BLACKOUT ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_BLACKOUT|ROAR_ROARDMX_ETYPE_OFF); self->emitting -= FLAG_BLACKOUT; } if ( self->emitting & FLAG_FULLON ) { roar_slfi_event_add(inst, ROAR_ROARDMX_EVENT_FULLON|ROAR_ROARDMX_ETYPE_OFF); self->emitting -= FLAG_FULLON; } if ( value != self->lastvalue ) roar_slfi_event_add(inst, self->event); self->lastvalue = value; } return 0; } static const struct roar_slfi_filter filter[1] = { { .name = "channel2event", .description = "SLFI filter mapping channel data to events", .flags = ROAR_SLFI_FLAG_ON_UPDATE, .init = __init, .uninit = NULL, .update = __update, .ctl = NULL } }; ROAR_DL_PLUGIN_REG_SLFI(filter); // This is the plugin control block. ROAR_DL_PLUGIN_START(filter_slfi_channel2event) { // 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-channel2event", 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 plugin allows to map DMX channel data to RoarDMX events."); // Load filters. ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_FILTER); // This is the end of the control block. } ROAR_DL_PLUGIN_END //ll