aboutsummaryrefslogtreecommitdiff
path: root/cyclone/sickle/capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/sickle/capture.c')
-rw-r--r--cyclone/sickle/capture.c408
1 files changed, 408 insertions, 0 deletions
diff --git a/cyclone/sickle/capture.c b/cyclone/sickle/capture.c
new file mode 100644
index 0000000..089c21e
--- /dev/null
+++ b/cyclone/sickle/capture.c
@@ -0,0 +1,408 @@
+/* Copyright (c) 2002-2003 krzYszcz and others.
+ * For information on usage and redistribution, and for a DISCLAIMER OF ALL
+ * WARRANTIES, see the file, "LICENSE.txt," in this distribution. */
+
+/* CHECKME list of indices */
+
+#include <stdio.h>
+#include "m_pd.h"
+#include "g_canvas.h"
+#include "common/loud.h"
+#include "hammer/file.h"
+#include "sickle/sic.h"
+
+#define CAPTURE_DEFSIZE 4096
+#define CAPTURE_DEFPRECISION 4
+#define CAPTURE_MAXPRECISION 99 /* format array protection */
+#define CAPTURE_MAXINDICES 4096 /* FIXME */
+
+typedef struct _capture
+{
+ t_sic x_sic;
+ t_glist *x_glist;
+ char x_mode; /* 'f' for first or 0 for last */
+ int x_precision;
+ char x_format[8];
+ char *x_indices;
+ int x_szindices; /* size of x_indices array */
+ int x_nindices; /* number of reported indices */
+ int x_nblock;
+ float *x_buffer;
+ int x_bufsize;
+ int x_count;
+ int x_head;
+ t_hammerfile *x_filehandle;
+} t_capture;
+
+static t_class *capture_class;
+
+static void capture_clear(t_capture *x)
+{
+ x->x_count = 0;
+ x->x_head = 0;
+}
+
+static int capture_formatfloat(t_capture *x, float f, char *buf, int col,
+ int maxcol)
+{
+ char *bp = buf;
+ int cnt = 0;
+ if (col > 0)
+ *bp++ = ' ', cnt++;
+ if (x->x_precision)
+ cnt += sprintf(bp, x->x_format, f);
+ else
+ cnt += sprintf(bp, "%d", (int)f);
+ if (col + cnt > maxcol)
+ buf[0] = '\n', col = cnt;
+ else
+ col += cnt;
+ return (col);
+}
+
+static int capture_writefloat(t_capture *x, float f, char *buf, int col,
+ FILE *fp)
+{
+ /* CHECKME linebreaks */
+ col = capture_formatfloat(x, f, buf, col, 80);
+ return (fputs(buf, fp) < 0 ? -1 : col);
+}
+
+static void capture_dowrite(t_capture *x, t_symbol *fn)
+{
+ FILE *fp = 0;
+ int count = x->x_count;
+ char buf[MAXPDSTRING];
+ canvas_makefilename(glist_getcanvas(x->x_glist),
+ fn->s_name, buf, MAXPDSTRING);
+ if (fp = fopen(buf, "w")) /* LATER ask if overwriting, CHECKME */
+ {
+ int col = 0;
+ if (x->x_mode == 'f' || count < x->x_bufsize)
+ {
+ float *bp = x->x_buffer;
+ while (count--)
+ if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0)
+ goto fail;
+ }
+ else
+ {
+ float *bp = x->x_buffer + x->x_head;
+ count = x->x_bufsize - x->x_head;
+ while (count--)
+ if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0)
+ goto fail;
+ bp = x->x_buffer;
+ count = x->x_head;
+ while (count--)
+ if ((col = capture_writefloat(x, *bp++, buf, col, fp)) < 0)
+ goto fail;
+ }
+ if (col) fputc('\n', fp);
+ fclose(fp);
+ return;
+ }
+fail:
+ if (fp) fclose(fp);
+ loud_syserror((t_pd *)x, 0);
+}
+
+static void capture_writehook(t_pd *z, t_symbol *fn, int ac, t_atom *av)
+{
+ capture_dowrite((t_capture *)z, fn);
+}
+
+static void capture_write(t_capture *x, t_symbol *s)
+{
+ if (s && s != &s_)
+ capture_dowrite(x, s);
+ else
+ hammerpanel_save(x->x_filehandle, 0, 0);
+}
+
+static int capture_appendfloat(t_capture *x, float f, char *buf,
+ int col, int linebreak)
+{
+ /* CHECKME 80 columns */
+ col = capture_formatfloat(x, f, buf, col, 80);
+ hammereditor_append(x->x_filehandle, buf);
+ if (linebreak)
+ {
+ if (col)
+ {
+ hammereditor_append(x->x_filehandle, "\n\n");
+ col = 0;
+ }
+ else hammereditor_append(x->x_filehandle, "\n");
+ }
+ return (col);
+}
+
+/* CHECKED blank line between blocks */
+static void capture_open(t_capture *x)
+{
+ int count = x->x_count;
+ char buf[MAXPDSTRING];
+ int nindices = (x->x_nindices > 0 ? x->x_nindices : x->x_nblock);
+ hammereditor_open(x->x_filehandle, "Signal Capture"); /* CHECKED */
+ if (x->x_mode == 'f' || count < x->x_bufsize)
+ {
+ float *bp = x->x_buffer;
+ int col = 0, i;
+ for (i = 1; i <= count; i++)
+ col = capture_appendfloat(x, *bp++, buf, col,
+ ((i % nindices) == 0));
+ }
+ else
+ {
+ float *bp = x->x_buffer + x->x_head;
+ int col = 0, i = x->x_bufsize;
+ count = x->x_bufsize - x->x_head;
+ while (count--)
+ col = capture_appendfloat(x, *bp++, buf, col,
+ ((--i % nindices) == 0));
+ bp = x->x_buffer;
+ count = x->x_head;
+ while (count--)
+ col = capture_appendfloat(x, *bp++, buf, col,
+ ((count % nindices) == 0));
+ }
+}
+
+static void capture_wclose(t_capture *x)
+{
+ hammereditor_close(x->x_filehandle, 0);
+}
+
+static void capture_click(t_capture *x, t_floatarg xpos, t_floatarg ypos,
+ t_floatarg shift, t_floatarg ctrl, t_floatarg alt)
+{
+ capture_open(x);
+}
+
+static t_int *capture_perform_first(t_int *w)
+{
+ t_capture *x = (t_capture *)(w[1]);
+ int count = x->x_count;
+ int bufsize = x->x_bufsize;
+ if (count < bufsize)
+ {
+ t_float *in = (t_float *)(w[2]);
+ int nblock = (int)(w[3]);
+ float *bp = x->x_buffer + count;
+ char *ndxp = x->x_indices;
+ if (nblock > x->x_szindices)
+ nblock = x->x_szindices;
+ while (nblock--)
+ {
+ if (*ndxp++)
+ {
+ *bp++ = *in++;
+ if (++count == bufsize)
+ break;
+ }
+ else in++;
+ }
+ x->x_count = count;
+ }
+ return (w + 4);
+}
+
+static t_int *capture_perform_allfirst(t_int *w)
+{
+ t_capture *x = (t_capture *)(w[1]);
+ int count = x->x_count;
+ int bufsize = x->x_bufsize;
+ if (count < bufsize)
+ {
+ t_float *in = (t_float *)(w[2]);
+ int nblock = (int)(w[3]);
+ float *bp = x->x_buffer + count;
+ while (nblock--)
+ {
+ *bp++ = *in++;
+ if (++count == bufsize)
+ break;
+ }
+ x->x_count = count;
+ }
+ return (w + 4);
+}
+
+static t_int *capture_perform_last(t_int *w)
+{
+ t_capture *x = (t_capture *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ int nblock = (int)(w[3]);
+ float *buffer = x->x_buffer;
+ int bufsize = x->x_bufsize;
+ int count = x->x_count;
+ int head = x->x_head;
+ char *ndxp = x->x_indices;
+ if (nblock > x->x_szindices)
+ nblock = x->x_szindices;
+ while (nblock--)
+ {
+ if (*ndxp++)
+ {
+ buffer[head++] = *in++;
+ if (head >= bufsize)
+ head = 0;
+ if (count < bufsize)
+ count++;
+ }
+ else in++;
+ }
+ x->x_count = count;
+ x->x_head = head;
+ return (w + 4);
+}
+
+static t_int *capture_perform_alllast(t_int *w)
+{
+ t_capture *x = (t_capture *)(w[1]);
+ t_float *in = (t_float *)(w[2]);
+ int nblock = (int)(w[3]);
+ float *buffer = x->x_buffer;
+ int bufsize = x->x_bufsize;
+ int count = x->x_count;
+ int head = x->x_head;
+ while (nblock--)
+ {
+ buffer[head++] = *in++;
+ if (head >= bufsize)
+ head = 0;
+ if (count < bufsize)
+ count++;
+ }
+ x->x_count = count;
+ x->x_head = head;
+ return (w + 4);
+}
+
+static void capture_dsp(t_capture *x, t_signal **sp)
+{
+ x->x_nblock = sp[0]->s_n;
+ if (x->x_indices)
+ dsp_add((x->x_mode == 'f' ?
+ capture_perform_first : capture_perform_last),
+ 3, x, sp[0]->s_vec, sp[0]->s_n);
+ else
+ dsp_add((x->x_mode == 'f' ?
+ capture_perform_allfirst : capture_perform_alllast),
+ 3, x, sp[0]->s_vec, sp[0]->s_n);
+}
+
+static void capture_free(t_capture *x)
+{
+ hammerfile_free(x->x_filehandle);
+ if (x->x_indices)
+ freebytes(x->x_indices, x->x_szindices * sizeof(*x->x_indices));
+ if (x->x_buffer)
+ freebytes(x->x_buffer, x->x_bufsize * sizeof(*x->x_buffer));
+}
+
+static void *capture_new(t_symbol *s, int ac, t_atom *av)
+{
+ t_capture *x = 0;
+ char mode = 0;
+ int precision = -1;
+ float *buffer;
+ int bufsize = 0;
+ char *indices = 0;
+ int szindices = 0, nindices = -1;
+ if (ac && av->a_type == A_SYMBOL)
+ {
+ t_symbol *s = av->a_w.w_symbol;
+ if (s && *s->s_name == 'f') /* CHECKME */
+ mode = 'f';
+ ac--; av++;
+ }
+ if (ac && av->a_type == A_FLOAT)
+ {
+ bufsize = (int)av->a_w.w_float; /* CHECKME */
+ ac--; av++;
+ if (ac && av->a_type == A_FLOAT)
+ {
+ int i;
+ t_atom *ap;
+ precision = (int)av->a_w.w_float; /* CHECKME */
+ ac--; av++;
+ for (i = 0, ap = av; i < ac; i++, ap++)
+ {
+ if (ap->a_type == A_FLOAT)
+ {
+ int ndx = (int)ap->a_w.w_float;
+ /* CHECKME noninteger, negative */
+ ndx++;
+ if (ndx >= CAPTURE_MAXINDICES)
+ {
+ /* CHECKME complaint */
+ szindices = CAPTURE_MAXINDICES;
+ break;
+ }
+ else if (ndx > szindices)
+ szindices = ndx;
+ }
+ else break; /* CHECKME */
+ }
+ if (szindices && (indices = getbytes(szindices * sizeof(*indices))))
+ {
+ nindices = 0;
+ while (i--)
+ {
+ int ndx = (int)av++->a_w.w_float;
+ /* CHECKME noninteger */
+ if (ndx >= 0 && ndx < szindices)
+ indices[ndx] = 1, nindices++;
+ }
+ }
+ }
+ }
+ if (bufsize <= 0) /* CHECKME */
+ bufsize = CAPTURE_DEFSIZE;
+ if (buffer = getbytes(bufsize * sizeof(*buffer)))
+ {
+ x = (t_capture *)pd_new(capture_class);
+ x->x_glist = canvas_getcurrent();
+ x->x_mode = mode;
+ if (precision < 0) /* CHECKME */
+ precision = CAPTURE_DEFPRECISION;
+ else if (precision > CAPTURE_MAXPRECISION) /* CHECKME */
+ precision = CAPTURE_MAXPRECISION;
+ if (x->x_precision = precision)
+ sprintf(x->x_format, "%%.%dg", precision);
+ x->x_indices = indices;
+ x->x_szindices = szindices;
+ x->x_nindices = nindices;
+ x->x_nblock = 64; /* redundant */
+ x->x_buffer = buffer;
+ x->x_bufsize = bufsize;
+ x->x_filehandle = hammerfile_new((t_pd *)x, 0, 0, capture_writehook, 0);
+ capture_clear(x);
+ }
+ else if (indices)
+ freebytes(indices, szindices * sizeof(*indices));
+ return (x);
+}
+
+void capture_tilde_setup(void)
+{
+ capture_class = class_new(gensym("capture~"),
+ (t_newmethod)capture_new,
+ (t_method)capture_free,
+ sizeof(t_capture), 0, A_GIMME, 0);
+ sic_setup(capture_class, capture_dsp, SIC_FLOATTOSIGNAL);
+ class_addmethod(capture_class, (t_method)capture_clear,
+ gensym("clear"), 0);
+ class_addmethod(capture_class, (t_method)capture_write,
+ gensym("write"), A_DEFSYM, 0);
+ class_addmethod(capture_class, (t_method)capture_open,
+ gensym("open"), 0);
+ class_addmethod(capture_class, (t_method)capture_wclose,
+ gensym("wclose"), 0);
+ class_addmethod(capture_class, (t_method)capture_click,
+ gensym("click"),
+ A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
+ hammerfile_setup(capture_class, 0);
+}