//codecfilter_roardmx.c: /* * Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2008-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 "roard.h" #ifndef ROAR_WITHOUT_DCOMP_LIGHT static inline int __read_sset(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) { uint16_t channel; uint8_t value; int i, c; // we ignore errors here at the moment as 0 not < -1 c = roar_roardmx_message_numchannels(mes); ROAR_DBG("light_check_stream(id=%i): Number of subframes: %u", id, c); for (i = 0; i < c; i++) { if ( roar_roardmx_message_get_chanval(mes, &channel, &value, i) == -1 ) return -1; if ( g_light_state.channels < channel ) { ROAR_WARN("light_check_stream(id=%i): Writing on non extisting DMX channel %u", id, channel); continue; } else { g_light_state.state[channel] = value; g_light_state.changes[channel] = 0xFF; // the channel changed } } return 0; } static inline int __read_rangeset(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) { uint16_t start, end; uint8_t value; size_t p; int i, c; // we ignore errors here at the moment as 0 not < -1 c = roar_roardmx_message_numchannels(mes); ROAR_DBG("__read_rangeset(id=%i, ...): Number of subframes: %u", id, c); for (i = 0; i < c; i++) { ROAR_DBG("__read_rangeset(id=%i, ...): i=%i", id, i); if ( roar_roardmx_message_get_rangeval(mes, &start, &end, &value, i) == -1 ) { ROAR_WARN("__read_rangeset(id=%i, ...): Can not read subframe: %i: %s", id, i, roar_errorstring); return -1; } ROAR_DBG("__read_rangeset(id=%i, ...): i=%i, start=%u, end=%u, value=%u", id, i, start, end, value); if ( start > end ) { ROAR_WARN("__read_rangeset(id=%i, ...): Bad RoarDMX Rangeset frame: start > end.", id); continue; } if ( g_light_state.channels < end ) { ROAR_WARN("__read_rangeset(id=%i, ...): Range out of DMX universe: %u-%u", id, start, end); continue; } for (p = start; p <= end; p++) { g_light_state.state[p] = value; g_light_state.changes[p] = 0xFF; // the channel changed } } return 0; } static inline int __read_events(int id, struct roar_stream_server * ss, struct roar_roardmx_message * mes) { const uint8_t * events; size_t len; (void)id, (void)ss; if ( roar_roardmx_message_get_events(mes, &events, &len) == -1 ) return -1; return light_dmxevent_add(events, len); } int cf_light_roardmx_read(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; unsigned char type; if ( roar_roardmx_message_recv(&mes, &(ss->vio)) == -1 ) return -1; if ( roar_roardmx_message_get_type(&mes, &type) == -1 ) return -1; switch (type) { case ROAR_ROARDMX_TYPE_SSET: return __read_sset(id, ss, &mes); break; case ROAR_ROARDMX_TYPE_RANGESET: return __read_rangeset(id, ss, &mes); break; case ROAR_ROARDMX_TYPE_EVENT: return __read_events(id, ss, &mes); break; } roar_err_set(ROAR_ERROR_NSTYPE); return -1; } static inline int __write_events(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; const uint8_t * events; size_t len; if ( light_dmxevent_read(&events, &len) == -1 ) return -1; // check if we need to send events at all: if ( len == 0 ) return 0; // ok, now let's build the message: if ( roar_roardmx_message_new_event(&mes) == -1 ) return -1; if ( roar_roardmx_message_add_events(&mes, events, len) == -1 ) return -1; // and send it: if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; return 0; } static inline int __write_channels(int id, struct roar_stream_server * ss) { struct roar_roardmx_message mes; int have_message = 0; int i; for (i = 0; i < g_light_state.channels; i++) { if ( g_light_state.outputchanges[i] ) { if ( !have_message ) if ( roar_roardmx_message_new_sset(&mes) == -1 ) return -1; have_message = 2; if ( roar_roardmx_message_add_chanval(&mes, i, g_light_state.output[i]) == -1 ) { if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; if ( roar_roardmx_message_new_sset(&mes) == -1 ) return -1; have_message = 1; } } } if ( have_message == 2 ) if ( roar_roardmx_message_send(&mes, &(ss->vio)) == -1 ) return -1; return 0; } int cf_light_roardmx_write(int id, struct roar_stream_server * ss) { if ( __write_events(id, ss) == -1 ) return -1; if ( __write_channels(id, ss) == -1 ) return -1; return 0; } #endif //ll