aboutsummaryrefslogtreecommitdiff
path: root/cyclone/hammer/capture.c
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone/hammer/capture.c')
-rw-r--r--cyclone/hammer/capture.c291
1 files changed, 291 insertions, 0 deletions
diff --git a/cyclone/hammer/capture.c b/cyclone/hammer/capture.c
new file mode 100644
index 0000000..b36c421
--- /dev/null
+++ b/cyclone/hammer/capture.c
@@ -0,0 +1,291 @@
+/* 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. */
+
+#include <stdio.h>
+#include "m_pd.h"
+#include "common/loud.h"
+#include "hammer/file.h"
+
+#define CAPTURE_DEFSIZE 512
+
+typedef struct _capture
+{
+ t_object x_ob;
+ t_canvas *x_canvas;
+ char x_intmode; /* if nonzero ('x' or 'm') floats are ignored */
+ 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_float(t_capture *x, t_float f)
+{
+ if (x->x_intmode && f != (int)f) /* CHECKME float */
+ return;
+ x->x_buffer[x->x_head++] = f;
+ if (x->x_head >= x->x_bufsize)
+ x->x_head = 0;
+ if (x->x_count < x->x_bufsize)
+ x->x_count++;
+}
+
+static void capture_list(t_capture *x, t_symbol *s, int ac, t_atom *av)
+{
+ while (ac--)
+ {
+ if (av->a_type == A_FLOAT) /* CHECKME */
+ capture_float(x, av->a_w.w_float);
+ av++;
+ }
+}
+
+static void capture_clear(t_capture *x)
+{
+ x->x_count = 0;
+ x->x_head = 0;
+}
+
+static void capture_count(t_capture *x)
+{
+ post("capture: %d items received", /* CHECKED */
+ x->x_count); /* CHECKED incompatible (4.07 seems buggy here) */
+}
+
+static void capture_dump(t_capture *x)
+{
+ int count = x->x_count;
+ if (count < x->x_bufsize)
+ {
+ float *bp = x->x_buffer;
+ while (count--)
+ outlet_float(((t_object *)x)->ob_outlet, *bp++);
+ }
+ else
+ {
+ float *bp = x->x_buffer + x->x_head;
+ count = x->x_bufsize - x->x_head;
+ while (count--)
+ outlet_float(((t_object *)x)->ob_outlet, *bp++);
+ bp = x->x_buffer;
+ count = x->x_head;
+ while (count--)
+ outlet_float(((t_object *)x)->ob_outlet, *bp++);
+ }
+}
+
+static int capture_formatint(int i, char *buf, int col,
+ int maxcol, char *fmt)
+{
+ char *bp = buf;
+ int cnt = 0;
+ if (col > 0)
+ *bp++ = ' ', cnt++;
+ cnt += sprintf(bp, fmt, i);
+ if (col + cnt > maxcol)
+ buf[0] = '\n', col = cnt;
+ else
+ col += cnt;
+ return (col);
+}
+
+static int capture_formatfloat(float f, char *buf, int col,
+ int maxcol, char *fmt)
+{
+ char *bp = buf;
+ int cnt = 0;
+ if (col > 0)
+ *bp++ = ' ', cnt++;
+ cnt += sprintf(bp, fmt, f);
+ if (col + cnt > maxcol)
+ buf[0] = '\n', col = cnt;
+ else
+ col += cnt;
+ return (col);
+}
+
+static int capture_formatnumber(t_capture *x, float f, char *buf,
+ int col, int maxcol)
+{
+ char intmode = x->x_intmode;
+ if (intmode == 'm')
+ intmode = (f < 128 && f > -128 ? 'd' : 'x'); /* CHECKME */
+ if (intmode == 'x')
+ col = capture_formatint((int)f, buf, col, maxcol, "%x");
+ else if (intmode)
+ col = capture_formatint((int)f, buf, col, maxcol, "%d");
+ else
+ col = capture_formatfloat(f, buf, col, maxcol, "%g");
+ return (col);
+}
+
+static int capture_writefloat(t_capture *x, float f, char *buf, int col,
+ FILE *fp)
+{
+ /* CHECKED no linebreaks (FIXME) */
+ col = capture_formatnumber(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(x->x_canvas, fn->s_name, buf, MAXPDSTRING);
+ if (fp = fopen(buf, "w")) /* LATER ask if overwriting, CHECKED */
+ {
+ int col = 0;
+ if (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)
+{
+ /* CHECKED 80 columns */
+ col = capture_formatnumber(x, f, buf, col, 80);
+ hammereditor_append(x->x_filehandle, buf);
+ return (col);
+}
+
+static void capture_open(t_capture *x)
+{
+ int count = x->x_count;
+ char buf[MAXPDSTRING];
+ hammereditor_open(x->x_filehandle, "t_capture"); /* CHECKED */
+ if (count < x->x_bufsize)
+ {
+ float *bp = x->x_buffer;
+ int col = 0;
+ while (count--)
+ col = capture_appendfloat(x, *bp++, buf, col);
+ }
+ else
+ {
+ float *bp = x->x_buffer + x->x_head;
+ int col = 0;
+ count = x->x_bufsize - x->x_head;
+ while (count--)
+ col = capture_appendfloat(x, *bp++, buf, col);
+ bp = x->x_buffer;
+ count = x->x_head;
+ while (count--)
+ col = capture_appendfloat(x, *bp++, buf, col);
+ }
+}
+
+/* CHECKED without asking and storing the changes */
+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 void capture_free(t_capture *x)
+{
+ hammerfile_free(x->x_filehandle);
+ if (x->x_buffer)
+ freebytes(x->x_buffer, x->x_bufsize * sizeof(*x->x_buffer));
+}
+
+static void *capture_new(t_symbol *s, t_floatarg f)
+{
+ t_capture *x = 0;
+ float *buffer;
+ int bufsize = (int)f; /* CHECKME */
+ if (bufsize <= 0) /* CHECKME */
+ bufsize = CAPTURE_DEFSIZE;
+ if (buffer = getbytes(bufsize * sizeof(*buffer)))
+ {
+ x = (t_capture *)pd_new(capture_class);
+ x->x_canvas = canvas_getcurrent();
+ if (s && s != &s_)
+ {
+ if (s == gensym("x"))
+ x->x_intmode = 'x';
+ else if (s == gensym("m"))
+ x->x_intmode = 'm';
+ else
+ x->x_intmode = 'd'; /* ignore floats */
+ }
+ x->x_buffer = buffer;
+ x->x_bufsize = bufsize;
+ outlet_new((t_object *)x, &s_float);
+ x->x_filehandle = hammerfile_new((t_pd *)x, 0, 0, capture_writehook, 0);
+ capture_clear(x);
+ }
+ return (x);
+}
+
+void capture_setup(void)
+{
+ capture_class = class_new(gensym("capture"),
+ (t_newmethod)capture_new,
+ (t_method)capture_free,
+ sizeof(t_capture), 0, A_DEFFLOAT, A_DEFSYM, 0);
+ class_addfloat(capture_class, capture_float);
+ class_addlist(capture_class, capture_list);
+ class_addmethod(capture_class, (t_method)capture_clear,
+ gensym("clear"), 0);
+ class_addmethod(capture_class, (t_method)capture_count,
+ gensym("count"), 0);
+ class_addmethod(capture_class, (t_method)capture_dump,
+ gensym("dump"), 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);
+}