//dmx-random.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2011-2013 * * 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 #define SAMPLES_PER_TICK 2 struct channel { int32_t endsamp; int32_t cursamp; unsigned char startval, endval; }; struct state { size_t startaddr; size_t len; struct channel * channels; }; static struct state * g_state; static struct state g_state_init = { .startaddr = 0, .len = 4, .channels = NULL }; static void calc_end(size_t index) { if ( g_state->channels[index].cursamp <= g_state->channels[index].endsamp ) return; g_state->channels[index].cursamp = 0; g_state->channels[index].endsamp = (int32_t)1 + (int32_t)roar_random_uint16() * (int32_t)SAMPLES_PER_TICK; g_state->channels[index].startval = g_state->channels[index].endval; if ( roar_random_uint16() < 32768 ) return; g_state->channels[index].endval = roar_random_uint16() & 0xE0; } static void calc_channel(size_t index) { // trel = cursamp/endsamp double trel = (double)g_state->channels[index].cursamp/(double)g_state->channels[index].endsamp; double valdiff = (double)(g_state->channels[index].endval - g_state->channels[index].startval)*trel; valdiff += (double)g_state->channels[index].startval; light_dmxchannel_set(g_state->startaddr + index, (unsigned char)(unsigned int)(int)valdiff); } static int _init (struct roar_dl_librarypara * para) { struct roar_keyval * p; p = roar_keyval_lookup(para->argv, "startaddr", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->startaddr = atoi(p->value); p = roar_keyval_lookup(para->argv, "len", para->argc, 1); if ( p != NULL && p->value != NULL ) g_state->len = atoi(p->value); g_state->channels = roar_mm_malloc(g_state->len*sizeof(struct channel)); if ( g_state->channels == NULL ) return -1; memset(g_state->channels, 0, g_state->len*sizeof(struct channel)); return 0; } static int _free (struct roar_dl_librarypara * para) { (void)para; if ( g_state->channels != NULL ) roar_mm_free(g_state->channels); g_state->channels = NULL; return 0; } static int _update (struct roar_dl_librarypara * para) { size_t i; (void)para; for (i = 0; i < g_state->len; i++) { calc_end(i); calc_channel(i); g_state->channels[i].cursamp += ROAR_OUTPUT_BUFFER_SAMPLES; } return 0; } static struct roar_dl_appsched sched = { .init = _init, .free = _free, .update = _update, .tick = NULL, .wait = NULL }; ROAR_DL_PLUGIN_START(dmx_random) { ROARD_DL_CHECK_VERSIONS(); ROAR_DL_PLUGIN_META_PRODUCT_NIV("dmx-random", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO); ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING); ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0); ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org"); ROAR_DL_PLUGIN_META_DESC("This generates random light effects using roard's DMX interface."); ROAR_DL_PLUGIN_REG_GLOBAL_DATA(g_state, g_state_init); ROAR_DL_PLUGIN_REG_APPSCHED(&sched); } ROAR_DL_PLUGIN_END //ll