source: roaraudio/plugins/universal/filter-slfi-random.c @ 6052:d48765b2475e

Last change on this file since 6052:d48765b2475e was 6052:d48765b2475e, checked in by phi, 9 years ago

updated copyright headers

File size: 5.8 KB
Line 
1//filter-slfi-random.c:
2
3/*
4 *      Copyright (C) Philipp 'ph3-der-loewe' Schafft - 2012-2015
5 *
6 *  This file is part of roard a part of RoarAudio,
7 *  a cross-platform sound system for both, home and professional use.
8 *  See README for details.
9 *
10 *  This file is free software; you can redistribute it and/or modify
11 *  it under the terms of the GNU General Public License version 3
12 *  as published by the Free Software Foundation.
13 *
14 *  RoarAudio is distributed in the hope that it will be useful,
15 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 *  GNU General Public License for more details.
18 *
19 *  You should have received a copy of the GNU General Public License
20 *  along with this software; see the file COPYING.  If not, write to
21 *  the Free Software Foundation, 51 Franklin Street, Fifth Floor,
22 *  Boston, MA 02110-1301, USA.
23 *
24 */
25
26#include <roaraudio.h>
27#include <libroarlight/libroarlight.h>
28
29#define MAX_CHANNELS  64
30
31struct slfi_channel {
32 ssize_t channel;
33 int32_t time_end;
34 int32_t time_cur;
35 int32_t time_max;
36 uint8_t value_start;
37 uint8_t value_end;
38};
39
40struct slfi_random {
41 struct slfi_channel channel[MAX_CHANNELS];
42 size_t channel_len;
43};
44
45static inline void parse_range(ssize_t * channel, ssize_t * channel_stop, const char * str) {
46 char * delm;
47 char * buf;
48
49 if ( strstr(str, "-") == NULL ) {
50  *channel = atoi(str);
51  *channel_stop = *channel;
52  return;
53 }
54
55 buf = roar_mm_strdup(str);
56 if ( buf == NULL ) {
57  ROAR_WARN("Can not allocate memory: %s", roar_errorstring);
58  *channel = 0;
59  *channel_stop = 0;
60  return;
61 }
62
63 delm = strstr(buf, "-");
64 *delm = 0;
65 delm++;
66
67 *channel = atoi(buf);
68 *channel_stop = atoi(delm);
69
70 if ( *channel_stop < *channel )
71  *channel_stop = *channel;
72
73 roar_mm_free(buf);
74}
75
76static int __init(struct roar_slfi_inst * inst, const struct roar_keyval * para, ssize_t paralen) {
77 struct slfi_random * self = roar_mm_malloc(sizeof(struct slfi_random));
78 const struct roar_keyval * kv;
79 ssize_t i;
80 int32_t time_max = 2000000L;
81 ssize_t channel, channel_stop;
82
83 if ( self == NULL )
84  return -1;
85
86 memset(self, 0, sizeof(*self));
87 inst->userdata = self;
88
89 for (i = 0; i < (ssize_t)MAX_CHANNELS; i++) {
90  self->channel[i].channel     = -1;
91  self->channel[i].time_end    =  0;
92  self->channel[i].time_cur    =  0;
93  self->channel[i].value_start =  0;
94 }
95
96 for (i = 0; i < paralen; i++) {
97  kv = &(para[i]);
98  if ( kv->key == NULL || kv->value == NULL )
99   continue;
100
101  if ( !strcmp(kv->key, "time-max") ) {
102   time_max = roar_str2usec(kv->value);
103   if ( time_max < 0 )
104    time_max = 2000000L;
105  } else if ( !strcmp(kv->key, "channel") ) {
106   parse_range(&channel, &channel_stop, kv->value);
107   for (; channel <= channel_stop; channel++) {
108    if ( self->channel_len == MAX_CHANNELS ) {
109     ROAR_WARN("__init(*): Can not add (list is full) channel: %s", kv->value);
110     continue;
111    }
112    self->channel[self->channel_len].channel = channel;
113    self->channel[self->channel_len].time_max = time_max;
114    self->channel_len++;
115   }
116  } else {
117   ROAR_WARN("__init(*): Unknown parameter: %s", kv->key);
118  }
119 }
120
121 return 0;
122}
123
124static inline void calc_end(struct slfi_channel * channel) {
125 if ( channel->time_cur <= channel->time_end )
126  return;
127
128 channel->time_cur = 0;
129 channel->time_end = (int32_t)1 + (int32_t)roar_random_uint16() * ((channel->time_max-1) / 65536L);
130 channel->value_start = channel->value_end;
131
132 if ( roar_random_uint16() < 32768 )
133  return;
134
135 channel->value_end = roar_random_uint16() & 0xE0;
136}
137
138static inline uint8_t calc_channel(struct slfi_channel * channel) {
139 double trel = (double)channel->time_cur/(double)channel->time_end;
140 double valdiff = (double)(channel->value_end - channel->value_start)*trel;
141
142 valdiff += (double)channel->value_start;
143
144 return (uint8_t)(unsigned int)(int)valdiff;
145}
146
147static 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) {
148 struct slfi_random * self = inst->userdata;
149 struct slfi_channel * channel;
150 size_t i;
151
152 (void)inst, (void)event, (void)eventlen;
153
154 for (i = 0; i < self->channel_len; i++) {
155  channel = &(self->channel[i]);
156  if ( channel->channel >= size_of_universe ) {
157   ROAR_WARN("__update(*): Universe too small for filter.");
158   continue;
159  }
160  calc_end(channel);
161  universe[channel->channel] = calc_channel(channel);
162  channel->time_cur += usecspassed;
163 }
164
165 return 0;
166}
167
168static const struct roar_slfi_filter filter[1] = {
169 {
170  .name = "random",
171  .description = "Random SLFI filter",
172  .flags = ROAR_SLFI_FLAG_ON_UPDATE,
173  .init = __init,
174  .uninit = NULL,
175  .update = __update,
176  .ctl = NULL
177 }
178};
179
180ROAR_DL_PLUGIN_REG_SLFI(filter);
181
182// This is the plugin control block.
183ROAR_DL_PLUGIN_START(filter_slfi_random) {
184 // Here we set the name and vendor of our plugin.
185 // If you have no Vendor ID you need to use ROAR_DL_PLUGIN_META_PRODUCT_NV().
186 ROAR_DL_PLUGIN_META_PRODUCT_NIV("filter-slfi-random", ROAR_VID_ROARAUDIO, ROAR_VNAME_ROARAUDIO);
187
188 // This sets the version of your plugin.
189 ROAR_DL_PLUGIN_META_VERSION(ROAR_VERSION_STRING);
190
191 // This sets the license of your plugin.
192 // If there is no tag for the license you use you can just
193 // use ROAR_DL_PLUGIN_META_LICENSE().
194 ROAR_DL_PLUGIN_META_LICENSE_TAG(GPLv3_0);
195
196 // This sets the author and contact infos.
197 // There are several other macros to do this with other parameters.
198 // See ROAR_DL_PLUGIN_META_CONTACT*() in the header or documentation.
199 ROAR_DL_PLUGIN_META_CONTACT_FLNE("Philipp", "Schafft", "ph3-der-loewe", "lion@lion.leolix.org");
200
201 // This sets the description for your plugin.
202 ROAR_DL_PLUGIN_META_DESC("This plugin sets random values. It can be used for fireflies or moodlights");
203
204 // Load filters.
205 ROAR_DL_PLUGIN_REG_FNFUNC(ROAR_DL_FN_FILTER);
206
207// This is the end of the control block.
208} ROAR_DL_PLUGIN_END
209
210//ll
Note: See TracBrowser for help on using the repository browser.