summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac1
-rw-r--r--src/Makefile.am2
-rw-r--r--src/modules/Makefile.am2
-rw-r--r--src/modules/mixer/Makefile.am3
-rw-r--r--src/modules/mixer/mixer.c302
-rw-r--r--src/til.c2
6 files changed, 310 insertions, 2 deletions
diff --git a/configure.ac b/configure.ac
index 7e09e6a..f523ece 100644
--- a/configure.ac
+++ b/configure.ac
@@ -49,6 +49,7 @@ AC_CONFIG_FILES([
src/modules/flui2d/Makefile
src/modules/julia/Makefile
src/modules/meta2d/Makefile
+ src/modules/mixer/Makefile
src/modules/moire/Makefile
src/modules/montage/Makefile
src/modules/pixbounce/Makefile
diff --git a/src/Makefile.am b/src/Makefile.am
index f8d717d..b5f4e62 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -3,7 +3,7 @@ SUBDIRS = libs modules
noinst_LTLIBRARIES = libtil.la
libtil_la_SOURCES = til.c til.h til_args.c til_args.h til_fb.c til_fb.h til_jenkins.c til_jenkins.h til_limits.h til_module_context.c til_module_context.h til_settings.h til_settings.c til_setup.c til_setup.h til_stream.c til_stream.h til_tap.h til_threads.c til_threads.h til_util.c til_util.h
libtil_la_CPPFLAGS = -I@top_srcdir@/src
-libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/rkt/librkt.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/strobe/libstrobe.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/rocket/librocket.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la
+libtil_la_LIBADD = modules/blinds/libblinds.la modules/checkers/libcheckers.la modules/compose/libcompose.la modules/drizzle/libdrizzle.la modules/flui2d/libflui2d.la modules/julia/libjulia.la modules/meta2d/libmeta2d.la modules/mixer/libmixer.la modules/moire/libmoire.la modules/montage/libmontage.la modules/pixbounce/libpixbounce.la modules/plasma/libplasma.la modules/plato/libplato.la modules/ray/libray.la modules/rkt/librkt.la modules/roto/libroto.la modules/rtv/librtv.la modules/shapes/libshapes.la modules/snow/libsnow.la modules/sparkler/libsparkler.la modules/spiro/libspiro.la modules/stars/libstars.la modules/strobe/libstrobe.la modules/submit/libsubmit.la modules/swab/libswab.la modules/swarm/libswarm.la modules/voronoi/libvoronoi.la libs/grid/libgrid.la libs/puddle/libpuddle.la libs/ray/libray.la libs/rocket/librocket.la libs/sig/libsig.la libs/txt/libtxt.la libs/ascii/libascii.la libs/din/libdin.la
bin_PROGRAMS = rototiller
rototiller_SOURCES = fps.c fps.h main.c mem_fb.c setup.h setup.c til.h til_fb.c til_fb.h til_settings.c til_settings.h til_threads.c til_threads.h til_util.c til_util.h
diff --git a/src/modules/Makefile.am b/src/modules/Makefile.am
index c1326ac..d34e0c7 100644
--- a/src/modules/Makefile.am
+++ b/src/modules/Makefile.am
@@ -1 +1 @@
-SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d moire montage pixbounce plasma plato ray rkt roto rtv shapes snow sparkler spiro stars strobe submit swab swarm voronoi
+SUBDIRS = blinds checkers compose drizzle flui2d julia meta2d mixer moire montage pixbounce plasma plato ray rkt roto rtv shapes snow sparkler spiro stars strobe submit swab swarm voronoi
diff --git a/src/modules/mixer/Makefile.am b/src/modules/mixer/Makefile.am
new file mode 100644
index 0000000..8d265d5
--- /dev/null
+++ b/src/modules/mixer/Makefile.am
@@ -0,0 +1,3 @@
+noinst_LTLIBRARIES = libmixer.la
+libmixer_la_SOURCES = mixer.c
+libmixer_la_CPPFLAGS = -I@top_srcdir@/src -I@top_srcdir@/src/libs
diff --git a/src/modules/mixer/mixer.c b/src/modules/mixer/mixer.c
new file mode 100644
index 0000000..55234d3
--- /dev/null
+++ b/src/modules/mixer/mixer.c
@@ -0,0 +1,302 @@
+#include <math.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
+#include "til.h"
+#include "til_fb.h"
+#include "til_module_context.h"
+#include "til_settings.h"
+#include "til_stream.h"
+#include "til_tap.h"
+#include "til_util.h"
+
+/* Copyright (C) 2023 - Vito Caputo <vcaputo@pengaru.com> */
+
+/* This implements a rudimentary mixing module for things like fades */
+
+typedef enum mixer_style_t {
+ MIXER_STYLE_FLICKER,
+} mixer_style_t;
+
+typedef struct mixer_input_t {
+ til_module_context_t *module_ctxt;
+ /* XXX: it's expected that inputs will get more settable attributes to stick in here */
+} mixer_input_t;
+
+typedef struct mixer_context_t {
+ til_module_context_t til_module_context;
+
+ struct {
+ til_tap_t T;
+ } taps;
+
+ struct {
+ float T;
+ } vars;
+
+ float *T;
+
+ size_t n_inputs;
+ mixer_input_t inputs[];
+} mixer_context_t;
+
+typedef struct mixer_setup_input_t {
+ char *module;
+ til_setup_t *setup;
+} mixer_setup_input_t;
+
+typedef struct mixer_setup_t {
+ til_setup_t til_setup;
+
+ mixer_style_t style;
+ size_t n_inputs;
+ mixer_setup_input_t inputs[];
+} mixer_setup_t;
+
+#define MIXER_DEFAULT_STYLE MIXER_STYLE_FLICKER
+
+static til_module_context_t * mixer_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup);
+static void mixer_destroy_context(til_module_context_t *context);
+static void mixer_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr);
+static int mixer_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup);
+
+
+til_module_t mixer_module = {
+ .create_context = mixer_create_context,
+ .destroy_context = mixer_destroy_context,
+ .render_fragment = mixer_render_fragment,
+ .name = "mixer",
+ .description = "Module blender",
+ .setup = mixer_setup,
+ .flags = TIL_MODULE_EXPERIMENTAL,
+};
+
+
+static til_module_context_t * mixer_create_context(const til_module_t *module, til_stream_t *stream, unsigned seed, unsigned ticks, unsigned n_cpus, til_setup_t *setup)
+{
+ mixer_setup_t *s = (mixer_setup_t *)setup;
+ mixer_context_t *ctxt;
+ int r;
+
+ assert(setup);
+
+ ctxt = til_module_context_new(module, sizeof(mixer_context_t) + s->n_inputs * sizeof(mixer_input_t), stream, seed, ticks, n_cpus, setup);
+ if (!ctxt)
+ return NULL;
+
+ for (size_t i = 0; i < s->n_inputs; i++) {
+ const til_module_t *input_module;
+ input_module = til_lookup_module(((mixer_setup_t *)setup)->inputs[i].module);
+ r = til_module_create_context(input_module, stream, rand_r(&seed), ticks, n_cpus, s->inputs[i].setup, &ctxt->inputs[i].module_ctxt);
+ if (r < 0)
+ return til_module_context_free(&ctxt->til_module_context);
+
+ ctxt->n_inputs++;
+ }
+
+ ctxt->taps.T = til_tap_init_float(ctxt, &ctxt->T, 1, &ctxt->vars.T, "T");
+
+ return &ctxt->til_module_context;
+}
+
+
+static void mixer_destroy_context(til_module_context_t *context)
+{
+ mixer_context_t *ctxt = (mixer_context_t *)context;
+
+ for (size_t i = 0; i < ctxt->n_inputs; i++)
+ til_module_context_free(ctxt->inputs[i].module_ctxt);
+
+ free(context);
+}
+
+static inline float randf(unsigned *seed)
+{
+ return 1.f / RAND_MAX * rand_r(seed);
+}
+
+static void mixer_render_fragment(til_module_context_t *context, til_stream_t *stream, unsigned ticks, unsigned cpu, til_fb_fragment_t **fragment_ptr)
+{
+ mixer_context_t *ctxt = (mixer_context_t *)context;
+ til_fb_fragment_t *fragment = *fragment_ptr;
+ size_t i = 0;
+
+ if (!til_stream_tap_context(stream, context, NULL, &ctxt->taps.T))
+ *ctxt->T = cosf(ticks * .001f) * .5f + .5f;
+
+ switch (((mixer_setup_t *)context->setup)->style) {
+ case MIXER_STYLE_FLICKER:
+ if (randf(&context->seed) < *ctxt->T)
+ i = 1;
+ else
+ i = 0;
+ break;
+
+ default:
+ assert(0);
+ }
+
+ //for (size_t i = 0; i < ctxt->n_inputs; i++)
+ til_module_render(ctxt->inputs[i].module_ctxt, stream, ticks, &fragment);
+
+ *fragment_ptr = fragment;
+}
+
+
+static void mixer_setup_free(til_setup_t *setup)
+{
+ mixer_setup_t *s = (mixer_setup_t *)setup;
+
+ if (s) {
+ for (size_t i = 0; i < s->n_inputs; i++) {
+ free(s->inputs[i].module);
+ til_setup_free(s->inputs[i].setup);
+ }
+ free(setup);
+ }
+}
+
+
+static int mixer_setup(const til_settings_t *settings, til_setting_t **res_setting, const til_setting_desc_t **res_desc, til_setup_t **res_setup)
+{
+ const char *style_values[] = {
+ "flicker",
+ NULL
+ };
+ const char *style;
+ const til_settings_t *inputs_settings;
+ const char *inputs;
+ int r;
+
+ r = til_settings_get_and_describe_value(settings,
+ &(til_setting_spec_t){
+ .name = "Mixer blend style",
+ .key = "style",
+ .values = style_values,
+ .preferred = style_values[MIXER_DEFAULT_STYLE],
+ .annotations = NULL
+ },
+ &style,
+ res_setting,
+ res_desc);
+ if (r)
+ return r;
+
+ r = til_settings_get_and_describe_value(settings,
+ &(til_setting_spec_t){
+ .name = "Comma-separated list of module inputs",
+ .key = "inputs",
+ .preferred = "stars,plato",
+ .annotations = NULL,
+ //.random = mixer_random_inputs_setting,
+ .as_nested_settings = 1,
+ },
+ &inputs, /* XXX: unused in raw-value form, we want the settings instance */
+ res_setting,
+ res_desc);
+ if (r)
+ return r;
+
+ assert(res_setting && *res_setting && (*res_setting)->value_as_nested_settings);
+ inputs_settings = (*res_setting)->value_as_nested_settings;
+ {
+ til_setting_t *input_setting;
+
+ for (size_t i = 0; til_settings_get_value_by_idx(inputs_settings, i, &input_setting); i++) {
+ if (!input_setting->value_as_nested_settings) {
+ r = til_setting_desc_new( inputs_settings,
+ &(til_setting_spec_t){
+ .as_nested_settings = 1,
+ }, res_desc);
+ if (r < 0)
+ return r;
+
+ *res_setting = input_setting;
+
+ return 1;
+ }
+ }
+
+ for (size_t i = 0; til_settings_get_value_by_idx(inputs_settings, i, &input_setting); i++) {
+ til_setting_t *input_module_setting;
+ const char *input = til_settings_get_value_by_idx(input_setting->value_as_nested_settings, 0, &input_module_setting);
+ const til_module_t *input_module;
+
+ if (!input_module_setting)
+ return -EINVAL;
+
+ if (!input_module_setting->desc) {
+ r = til_setting_desc_new( input_setting->value_as_nested_settings,
+ &(til_setting_spec_t){
+ .name = "Input module name",
+ .preferred = "none",
+ .as_label = 1,
+ }, res_desc);
+ if (r < 0)
+ return r;
+
+ *res_setting = input_module_setting;
+
+ return 1;
+ }
+
+ input_module = til_lookup_module(input);
+ if (!input_module)
+ return -EINVAL;
+
+ if (input_module->setup) {
+ r = input_module->setup(input_setting->value_as_nested_settings, res_setting, res_desc, NULL);
+ if (r)
+ return r;
+ }
+ }
+ }
+
+ if (res_setup) {
+ size_t n_inputs = til_settings_get_count(inputs_settings);
+ til_setting_t *input_setting;
+ mixer_setup_t *setup;
+
+ setup = til_setup_new(settings, sizeof(*setup) + n_inputs * sizeof(setup->inputs[0]), mixer_setup_free);
+ if (!setup)
+ return -ENOMEM;
+
+ for (int i = 0; style_values[i]; i++) {
+ if (!strcasecmp(style_values[i], style))
+ setup->style = i;
+ }
+
+ setup->n_inputs = n_inputs;
+
+ for (size_t i = 0; til_settings_get_value_by_idx(inputs_settings, i, &input_setting); i++) {
+ const char *input = til_settings_get_value_by_idx(input_setting->value_as_nested_settings, 0, NULL);
+ const til_module_t *input_module;
+
+ setup->inputs[i].module = strdup(input);
+ if (!setup->inputs[i].module) {
+ til_setup_free(&setup->til_setup);
+
+ return -ENOMEM;
+ }
+
+ input_module = til_lookup_module(input);
+ if (!input_module) {
+ til_setup_free(&setup->til_setup);
+
+ return -EINVAL;
+ }
+
+ r = til_module_setup_finalize(input_module, input_setting->value_as_nested_settings, &setup->inputs[i].setup);
+ if (r < 0) {
+ til_setup_free(&setup->til_setup);
+
+ return r;
+ }
+ }
+
+ *res_setup = &setup->til_setup;
+ }
+
+ return 0;
+}
diff --git a/src/til.c b/src/til.c
index e62fb8e..8b9e382 100644
--- a/src/til.c
+++ b/src/til.c
@@ -32,6 +32,7 @@ extern til_module_t drizzle_module;
extern til_module_t flui2d_module;
extern til_module_t julia_module;
extern til_module_t meta2d_module;
+extern til_module_t mixer_module;
extern til_module_t moire_module;
extern til_module_t montage_module;
extern til_module_t pixbounce_module;
@@ -60,6 +61,7 @@ static const til_module_t *modules[] = {
&flui2d_module,
&julia_module,
&meta2d_module,
+ &mixer_module,
&moire_module,
&montage_module,
&pixbounce_module,
© All Rights Reserved