summaryrefslogtreecommitdiff
path: root/plugins/dumb/dumb-kode54/src/core/rendsig.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/dumb/dumb-kode54/src/core/rendsig.c')
-rw-r--r--plugins/dumb/dumb-kode54/src/core/rendsig.c344
1 files changed, 344 insertions, 0 deletions
diff --git a/plugins/dumb/dumb-kode54/src/core/rendsig.c b/plugins/dumb/dumb-kode54/src/core/rendsig.c
new file mode 100644
index 00000000..b8f866c5
--- /dev/null
+++ b/plugins/dumb/dumb-kode54/src/core/rendsig.c
@@ -0,0 +1,344 @@
+/* _______ ____ __ ___ ___
+ * \ _ \ \ / \ / \ \ / / ' ' '
+ * | | \ \ | | || | \/ | . .
+ * | | | | | | || ||\ /| |
+ * | | | | | | || || \/ | | ' ' '
+ * | | | | | | || || | | . .
+ * | |_/ / \ \__// || | |
+ * /_______/ynamic \____/niversal /__\ /____\usic /| . . ibliotheque
+ * / \
+ * / . \
+ * rendsig.c - Wrappers to render samples from / / \ \
+ * the signals in a DUH. | < / \_
+ * | \/ /\ /
+ * By entheh. \_ / > /
+ * | \ / /
+ * | ' /
+ * \__/
+ */
+
+#include <stdlib.h>
+
+#include "dumb.h"
+#include "internal/dumb.h"
+
+
+
+struct DUH_SIGRENDERER
+{
+ DUH_SIGTYPE_DESC *desc;
+
+ sigrenderer_t *sigrenderer;
+
+ int n_channels;
+
+ long pos;
+ int subpos;
+
+ DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback;
+ void *callback_data;
+};
+
+
+
+DUH_SIGRENDERER *duh_start_sigrenderer(DUH *duh, int sig, int n_channels, long pos)
+{
+ DUH_SIGRENDERER *sigrenderer;
+
+ DUH_SIGNAL *signal;
+ DUH_START_SIGRENDERER proc;
+
+ if (!duh)
+ return NULL;
+
+ if ((unsigned int)sig >= (unsigned int)duh->n_signals)
+ return NULL;
+
+ signal = duh->signal[sig];
+ if (!signal)
+ return NULL;
+
+ sigrenderer = malloc(sizeof(*sigrenderer));
+ if (!sigrenderer)
+ return NULL;
+
+ sigrenderer->desc = signal->desc;
+
+ proc = sigrenderer->desc->start_sigrenderer;
+
+ if (proc) {
+ duh->signal[sig] = NULL;
+ sigrenderer->sigrenderer = (*proc)(duh, signal->sigdata, n_channels, pos);
+ duh->signal[sig] = signal;
+
+ if (!sigrenderer->sigrenderer) {
+ free(sigrenderer);
+ return NULL;
+ }
+ } else
+ sigrenderer->sigrenderer = NULL;
+
+ sigrenderer->n_channels = n_channels;
+
+ sigrenderer->pos = pos;
+ sigrenderer->subpos = 0;
+
+ sigrenderer->callback = NULL;
+
+ return sigrenderer;
+}
+
+
+
+#include <stdio.h>
+void duh_sigrenderer_set_callback(
+ DUH_SIGRENDERER *sigrenderer,
+ DUH_SIGRENDERER_CALLBACK callback, void *data
+)
+{
+ (void)sigrenderer;
+ (void)callback;
+ (void)data;
+ /*fprintf(stderr,
+ "Call to deprecated function duh_sigrenderer_set_callback(). The callback\n"
+ "was not installed. See dumb/docs/deprec.txt for how to fix this.\n");*/
+}
+
+
+
+void duh_sigrenderer_set_analyser_callback(
+ DUH_SIGRENDERER *sigrenderer,
+ DUH_SIGRENDERER_ANALYSER_CALLBACK callback, void *data
+)
+{
+ (void)sigrenderer;
+ (void)callback;
+ (void)data;
+ fprintf(stderr,
+ "Call to deprecated function duh_sigrenderer_set_analyser_callback(). The\n"
+ "callback was not installed. See dumb/docs/deprec.txt for how to fix this.\n");
+}
+
+
+
+void duh_sigrenderer_set_sample_analyser_callback(
+ DUH_SIGRENDERER *sigrenderer,
+ DUH_SIGRENDERER_SAMPLE_ANALYSER_CALLBACK callback, void *data
+)
+{
+ if (sigrenderer) {
+ sigrenderer->callback = callback;
+ sigrenderer->callback_data = data;
+ }
+}
+
+
+
+int duh_sigrenderer_get_n_channels(DUH_SIGRENDERER *sigrenderer)
+{
+ return sigrenderer ? sigrenderer->n_channels : 0;
+}
+
+
+
+long duh_sigrenderer_get_position(DUH_SIGRENDERER *sigrenderer)
+{
+ return sigrenderer ? sigrenderer->pos : -1;
+}
+
+
+
+void duh_sigrenderer_set_sigparam(
+ DUH_SIGRENDERER *sigrenderer,
+ unsigned char id, long value
+)
+{
+ DUH_SIGRENDERER_SET_SIGPARAM proc;
+
+ if (!sigrenderer) return;
+
+ proc = sigrenderer->desc->sigrenderer_set_sigparam;
+ if (proc)
+ (*proc)(sigrenderer->sigrenderer, id, value);
+ else
+ TRACE("Parameter #%d = %ld for signal %c%c%c%c, which does not take parameters.\n",
+ (int)id,
+ value,
+ (int)(sigrenderer->desc->type >> 24),
+ (int)(sigrenderer->desc->type >> 16),
+ (int)(sigrenderer->desc->type >> 8),
+ (int)(sigrenderer->desc->type));
+}
+
+
+
+long duh_sigrenderer_generate_samples(
+ DUH_SIGRENDERER *sigrenderer,
+ float volume, float delta,
+ long size, sample_t **samples
+)
+{
+ long rendered;
+ LONG_LONG t;
+
+ if (!sigrenderer) return 0;
+
+ rendered = (*sigrenderer->desc->sigrenderer_generate_samples)
+ (sigrenderer->sigrenderer, volume, delta, size, samples);
+
+ if (rendered) {
+ if (sigrenderer->callback)
+ (*sigrenderer->callback)(sigrenderer->callback_data,
+ (const sample_t *const *)samples, sigrenderer->n_channels, rendered);
+
+ t = sigrenderer->subpos + (LONG_LONG)(delta * 65536.0 + 0.5) * rendered;
+
+ sigrenderer->pos += (long)(t >> 16);
+ sigrenderer->subpos = (int)t & 65535;
+ }
+
+ return rendered;
+}
+
+
+
+/* DEPRECATED */
+long duh_sigrenderer_get_samples(
+ DUH_SIGRENDERER *sigrenderer,
+ float volume, float delta,
+ long size, sample_t **samples
+)
+{
+ sample_t **s;
+ long rendered;
+ long i;
+ int j;
+ if (!samples) return duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, NULL);
+ s = allocate_sample_buffer(sigrenderer->n_channels, size);
+ if (!s) return 0;
+ dumb_silence(s[0], sigrenderer->n_channels * size);
+ rendered = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, s);
+ for (j = 0; j < sigrenderer->n_channels; j++)
+ for (i = 0; i < rendered; i++)
+ samples[j][i] += s[0][i*sigrenderer->n_channels+j];
+ destroy_sample_buffer(s);
+ return rendered;
+}
+
+
+
+/* DEPRECATED */
+long duh_render_signal(
+ DUH_SIGRENDERER *sigrenderer,
+ float volume, float delta,
+ long size, sample_t **samples
+)
+{
+ sample_t **s;
+ long rendered;
+ long i;
+ int j;
+ if (!samples) return duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, NULL);
+ s = allocate_sample_buffer(sigrenderer->n_channels, size);
+ if (!s) return 0;
+ dumb_silence(s[0], sigrenderer->n_channels * size);
+ rendered = duh_sigrenderer_generate_samples(sigrenderer, volume, delta, size, s);
+ for (j = 0; j < sigrenderer->n_channels; j++)
+ for (i = 0; i < rendered; i++)
+ samples[j][i] += s[0][i*sigrenderer->n_channels+j] >> 8;
+ destroy_sample_buffer(s);
+ return rendered;
+}
+
+
+
+void duh_sigrenderer_get_current_sample(DUH_SIGRENDERER *sigrenderer, float volume, sample_t *samples)
+{
+ if (sigrenderer)
+ (*sigrenderer->desc->sigrenderer_get_current_sample)(sigrenderer->sigrenderer, volume, samples);
+}
+
+
+
+void duh_end_sigrenderer(DUH_SIGRENDERER *sigrenderer)
+{
+ if (sigrenderer) {
+ if (sigrenderer->desc->end_sigrenderer)
+ if (sigrenderer->sigrenderer)
+ (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer);
+
+ free(sigrenderer);
+ }
+}
+
+
+
+DUH_SIGRENDERER *duh_encapsulate_raw_sigrenderer(sigrenderer_t *vsigrenderer, DUH_SIGTYPE_DESC *desc, int n_channels, long pos)
+{
+ DUH_SIGRENDERER *sigrenderer;
+
+ if (desc->start_sigrenderer && !vsigrenderer) return NULL;
+
+ sigrenderer = malloc(sizeof(*sigrenderer));
+ if (!sigrenderer) {
+ if (desc->end_sigrenderer)
+ if (vsigrenderer)
+ (*desc->end_sigrenderer)(vsigrenderer);
+ return NULL;
+ }
+
+ sigrenderer->desc = desc;
+ sigrenderer->sigrenderer = vsigrenderer;
+
+ sigrenderer->n_channels = n_channels;
+
+ sigrenderer->pos = pos;
+ sigrenderer->subpos = 0;
+
+ sigrenderer->callback = NULL;
+
+ return sigrenderer;
+}
+
+
+
+sigrenderer_t *duh_get_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type)
+{
+ if (sigrenderer && sigrenderer->desc->type == type)
+ return sigrenderer->sigrenderer;
+
+ return NULL;
+}
+
+
+
+#if 0
+// This function is disabled because we don't know whether we want to destroy
+// the sigrenderer if the type doesn't match. We don't even know if we need
+// the function at all. Who would want to keep an IT_SIGRENDERER (for
+// instance) without keeping the DUH_SIGRENDERER?
+sigrenderer_t *duh_decompose_to_raw_sigrenderer(DUH_SIGRENDERER *sigrenderer, long type)
+{
+ if (sigrenderer && sigrenderer->desc->type == type) {
+
+
+
+ if (sigrenderer) {
+ if (sigrenderer->desc->end_sigrenderer)
+ if (sigrenderer->sigrenderer)
+ (*sigrenderer->desc->end_sigrenderer)(sigrenderer->sigrenderer);
+
+ free(sigrenderer);
+ }
+
+
+
+
+
+
+ return sigrenderer->sigrenderer;
+ }
+
+ return NULL;
+}
+#endif