aboutsummaryrefslogtreecommitdiff
path: root/cyclone
diff options
context:
space:
mode:
Diffstat (limited to 'cyclone')
-rw-r--r--cyclone/Makefile.objects11
-rw-r--r--cyclone/Makefile.sources7
-rw-r--r--cyclone/build_counter2
-rw-r--r--cyclone/hammer/comment.c15
-rw-r--r--cyclone/shadow/Makefile.objects1
-rw-r--r--cyclone/shadow/Makefile.sources6
-rw-r--r--cyclone/shadow/cyclone.c48
-rw-r--r--cyclone/shadow/dummies.c51
-rw-r--r--cyclone/shadow/shadow.h3
-rw-r--r--cyclone/sickle/Makefile.sources1
-rw-r--r--cyclone/sickle/Scope.c14
-rw-r--r--cyclone/sickle/allsickles.c2
-rw-r--r--cyclone/sickle/buffir.c213
13 files changed, 309 insertions, 65 deletions
diff --git a/cyclone/Makefile.objects b/cyclone/Makefile.objects
index 9b421fe..87d7ae4 100644
--- a/cyclone/Makefile.objects
+++ b/cyclone/Makefile.objects
@@ -1,16 +1,17 @@
HLOUD_OBJECTS = common/loud.o
+HFORKY_OBJECTS = common/loud.o unstable/forky.o
HFRAGILE_OBJECTS = common/loud.o unstable/fragile.o
HGROW_OBJECTS = common/grow.o common/loud.o
-HFILE_OBJECTS = hammer/file.o common/loud.o
+HFILE_OBJECTS = hammer/file.o common/loud.o unstable/forky.o
HRAND_OBJECTS = common/rand.o common/loud.o
-HRANDFILE_OBJECTS = common/rand.o hammer/file.o common/loud.o
+HRANDFILE_OBJECTS = common/rand.o hammer/file.o common/loud.o unstable/forky.o
HRANDGROW_OBJECTS = common/rand.o common/grow.o common/loud.o
HTREE_OBJECTS = hammer/tree.o common/loud.o
HTREEFILEVEFL_OBJECTS = hammer/tree.o hammer/file.o \
- common/vefl.o common/loud.o unstable/fragile.o
+ common/vefl.o common/loud.o unstable/forky.o unstable/fragile.o
HGUI_OBJECTS = hammer/gui.o common/loud.o
HSEQ_OBJECTS = common/sq.o common/bifi.o common/mifi.o \
- hammer/file.o common/grow.o common/loud.o
+ hammer/file.o common/grow.o common/loud.o unstable/forky.o
SSIC_OBJECTS = sickle/sic.o common/loud.o
SFORKY_OBJECTS = sickle/sic.o common/loud.o unstable/forky.o
SFRAGILE_OBJECTS = sickle/sic.o common/loud.o unstable/fragile.o
@@ -19,6 +20,6 @@ SGROWFORKY_OBJECTS = common/grow.o sickle/sic.o common/loud.o unstable/forky.o
SVEFL_OBJECTS = common/vefl.o sickle/sic.o common/loud.o unstable/fragile.o
SARSIC_OBJECTS = sickle/sic.o sickle/arsic.o common/vefl.o \
common/loud.o unstable/fragile.o
-SFILE_OBJECTS = hammer/file.o sickle/sic.o common/loud.o
+SFILE_OBJECTS = hammer/file.o sickle/sic.o common/loud.o unstable/forky.o
RELEASE_LIBS = cyclone hammer sickle
RELEASE_APPS = cyclist
diff --git a/cyclone/Makefile.sources b/cyclone/Makefile.sources
index 818d8c8..f6e69bf 100644
--- a/cyclone/Makefile.sources
+++ b/cyclone/Makefile.sources
@@ -1,4 +1,4 @@
-TYPES = HPLAIN HLOUD HFRAGILE HGROW HFILE HRAND HRANDFILE HRANDGROW \
+TYPES = HPLAIN HLOUD HFORKY HFRAGILE HGROW HFILE HRAND HRANDFILE HRANDGROW \
HTREE HTREEFILEVEFL HGUI HSEQ \
SPLAINNOTILDE SPLAIN SSIC SFORKY SFRAGILE SGROW SGROWFORKY \
SVEFL SARSIC SFILE
@@ -40,7 +40,6 @@ HLOUD_SOURCES = \
hammer/anal.c \
hammer/bangbang.c \
hammer/Borax.c \
-hammer/comment.c \
hammer/cycle.c \
hammer/decide.c \
hammer/Decode.c \
@@ -54,6 +53,9 @@ hammer/sprintf.c \
hammer/switch.c \
hammer/TogEdge.c
+HFORKY_SOURCES = \
+hammer/comment.c
+
HFRAGILE_SOURCES = \
hammer/grab.c \
hammer/universal.c
@@ -192,6 +194,7 @@ sickle/cycle.c
SARSIC_TILDE = $(TILDE)
SARSIC_SOURCES = \
+sickle/buffir.c \
sickle/index.c \
sickle/lookup.c \
sickle/peek.c \
diff --git a/cyclone/build_counter b/cyclone/build_counter
index bce8105..0414f92 100644
--- a/cyclone/build_counter
+++ b/cyclone/build_counter
@@ -1,3 +1,3 @@
#define CYCLONE_VERSION "0.1"
#define CYCLONE_RELEASE "alpha"
-#define CYCLONE_BUILD 44
+#define CYCLONE_BUILD 45
diff --git a/cyclone/hammer/comment.c b/cyclone/hammer/comment.c
index 8e3baeb..3fe6ec6 100644
--- a/cyclone/hammer/comment.c
+++ b/cyclone/hammer/comment.c
@@ -13,6 +13,7 @@
#include "m_pd.h"
#include "g_canvas.h"
#include "common/loud.h"
+#include "unstable/forky.h"
/* our proxy of the text_class (not in the API), LATER do not cheat */
static t_class *makeshift_class;
@@ -443,7 +444,7 @@ static void comment_vis(t_gobj *z, t_glist *glist, int vis)
than complying to a Pd's assumption about every visible object
having an rtext (thus preventing canvas_doclick() from sending
garbage warnings). LATER revisit. */
-#ifndef PD_MINOR_VERSION
+#if FORKY_VERSION < 37
rtext_new(glist, t, glist->gl_editor->e_rtext, 0);
#endif
if (glist->gl_havewindow)
@@ -451,7 +452,7 @@ static void comment_vis(t_gobj *z, t_glist *glist, int vis)
}
else
{
-#ifndef PD_MINOR_VERSION
+#if FORKY_VERSION < 37
t_rtext *rt = glist_findrtext(glist, t);
if (rt) rtext_free(rt);
#endif
@@ -488,14 +489,7 @@ static t_widgetbehavior comment_widgetbehavior =
0,
comment_vis,
0,
- /* As of 0.37, pd does not have these last two elements in */
- /* a t_widgetbehavoir anymore. <hans@eds.org> */
-#if PD_MAJOR_VERSION == 0
-#if PD_MINOR_VERSION < 37 || !defined(PD_MINOR_VERSION)
- comment_save,
- 0,
-#endif
-#endif
+ FORKY_WIDGETPADDING
};
/* this fires if a transform request was sent to a symbol we are bound to */
@@ -813,6 +807,7 @@ void comment_setup(void)
class_addmethod(comment_class, (t_method)comment__motionhook,
gensym("_motion"), A_SYMBOL, A_FLOAT, A_FLOAT, 0);
class_setwidget(comment_class, &comment_widgetbehavior);
+ forky_setsavefn(comment_class, comment_save);
makeshift_class = class_new(gensym("text"), 0, 0,
sizeof(t_text),
diff --git a/cyclone/shadow/Makefile.objects b/cyclone/shadow/Makefile.objects
index f77675c..f06e939 100644
--- a/cyclone/shadow/Makefile.objects
+++ b/cyclone/shadow/Makefile.objects
@@ -5,5 +5,6 @@ common/binport.o \
common/port.o \
hammer/file.o \
sickle/sic.o \
+unstable/forky.o \
unstable/fragile.o \
unstable/loader.o
diff --git a/cyclone/shadow/Makefile.sources b/cyclone/shadow/Makefile.sources
index 8ba4681..061f37b 100644
--- a/cyclone/shadow/Makefile.sources
+++ b/cyclone/shadow/Makefile.sources
@@ -1,6 +1,6 @@
CX_SOURCES = \
-cyclone.c
+cyclone.c \
+dummies.c
OTHER_SOURCES = \
-nettles.c \
-dummies.c
+nettles.c
diff --git a/cyclone/shadow/cyclone.c b/cyclone/shadow/cyclone.c
index 047d39d..10ae142 100644
--- a/cyclone/shadow/cyclone.c
+++ b/cyclone/shadow/cyclone.c
@@ -28,6 +28,8 @@ static int cyclone_nettlesndx;
static int cyclone_dummiesndx;
static int cyclone_lastndx;
+static t_pd *cyclone_dproxy = 0;
+
static void cyclone_readhook(t_pd *z, t_symbol *fn, int ac, t_atom *av)
{
import_max(fn->s_name, "");
@@ -59,28 +61,33 @@ static void cyclone_bang(t_cyclone *x)
cyclone_sicklendx, cyclone_nettlesndx - 1);
fragile_class_printnames("nettles are: ",
cyclone_nettlesndx, cyclone_dummiesndx - 1);
- if (i = dummy_nreplacements())
- post("send 'reps' message to see the list of %d \
-replacement abstractions", i);
+ if (cyclone_dproxy)
+ pd_bang(cyclone_dproxy);
else
post("no replacement abstractions");
- post("send 'dummies' message to see the list of %d dummy classes",
- /* cyclone_lastndx points to the "_dummy" sentinel class */
- cyclone_lastndx - cyclone_dummiesndx);
+ if (cyclone_lastndx > cyclone_dummiesndx)
+ post("send 'dummies' message to see the list of %d dummy classes",
+ /* cyclone_lastndx points to the "_dummy" sentinel class */
+ cyclone_lastndx - cyclone_dummiesndx);
+ else
+ post("no dummies");
}
static void cyclone_reps(t_cyclone *x)
{
- if (dummy_nreplacements())
- dummy_printreplacements("replacement abstractions are: ");
+ if (cyclone_dproxy)
+ typedmess(cyclone_dproxy, gensym("reps"), 0, 0);
else
post("no replacement abstractions");
}
static void cyclone_dummies(t_cyclone *x)
{
- fragile_class_printnames("dummies are: ",
- cyclone_dummiesndx, cyclone_lastndx);
+ if (cyclone_lastndx > cyclone_dummiesndx)
+ fragile_class_printnames("dummies are: ",
+ cyclone_dummiesndx, cyclone_lastndx);
+ else
+ post("no dummies");
}
static void cyclone_free(t_cyclone *x)
@@ -98,8 +105,8 @@ static void *cyclone_new(t_symbol *s)
void cyclone_setup(void)
{
- int hresult, sresult;
- hresult = sresult = LOADER_OK;
+ int hresult, sresult, dresult;
+ hresult = sresult = dresult = LOADER_OK;
if (canvas_getcurrent())
{
/* Loading the library by object creation is banned, because of a danger
@@ -142,7 +149,11 @@ void cyclone_setup(void)
allnettles_setup();
cyclone_dummiesndx = fragile_class_count();
- alldummies_setup();
+ if (zgetfn(&pd_objectmaker, gensym("dummies")))
+ loud_warning(0, "dummies are already loaded");
+ else
+ dresult = unstable_load_lib("", "dummies");
+
cyclone_lastndx = fragile_class_count() - 1;
if (hresult == LOADER_NOFILE)
@@ -156,4 +167,15 @@ void cyclone_setup(void)
loud_errand(0,
"use a more recent Pd release (or recompile the cyclone).");
}
+ else if (dresult == LOADER_NOFILE)
+ loud_warning(0, "dummies not found");
+ else
+ {
+ t_symbol *s = gensym("_ccdummies");
+ if (s->s_thing && !s->s_next
+ && !strcmp(class_getname(*s->s_thing), "_ccdummies"))
+ cyclone_dproxy = s->s_thing;
+ else
+ bug("cyclone_setup"); /* FIXME */
+ }
}
diff --git a/cyclone/shadow/dummies.c b/cyclone/shadow/dummies.c
index be9a886..c6d53fe 100644
--- a/cyclone/shadow/dummies.c
+++ b/cyclone/shadow/dummies.c
@@ -11,8 +11,8 @@
#endif
#include "m_pd.h"
#include "common/loud.h"
-#include "shadow.h"
+static t_class *ccdummies_class;
static int dummy_nclasses = 0;
static t_class **dummy_classes;
static int dummy_nreps = 0;
@@ -351,7 +351,6 @@ static t_dummy_slot dummy_slots[] =
{ "Biquad~", 6, 1, 0, 0 },
/* LATER try mapping bpatcher to a gop abstraction/subpatch */
{ "buffer~", 1, 2, 0, 0 },
- { "buffir~", 3, 1, 0, 0 },
{ "cd", 1, 2, 0, 0 }, /* CHECKED (refman error?) */
{ "cd~", 1, 6, 0, 0 }, /* CHECKED (refman error?) */
{ "Change", 1, 3, 0, 0 },
@@ -554,34 +553,43 @@ static t_object *dummy_newobject(t_symbol *s, t_dummy_slot **slotp)
return (x);
}
-int dummy_nreplacements(void)
+static void ccdummies_bang(t_pd *x)
{
- return (dummy_nreps);
+ if (dummy_nreps)
+ post("send 'reps' message to see the list of %d \
+replacement abstractions", dummy_nreps);
+ else
+ post("no replacement abstractions");
}
-void dummy_printreplacements(char *msg)
+static void ccdummies_reps(t_pd *x)
{
- int i, len = strlen(msg);
- t_dummy_slot *sl;
- startpost(msg);
- for (i = 0, sl = dummy_slots; i < dummy_nclasses; i++, sl++)
+ if (dummy_nreps)
{
- if (!dummy_classes[i])
+ char *msg = "replacement abstractions are: ";
+ int i, len = strlen(msg);
+ t_dummy_slot *sl;
+ startpost(msg);
+ for (i = 0, sl = dummy_slots; i < dummy_nclasses; i++, sl++)
{
- int l = 1 + strlen(sl->s_name);
- if ((len += l) > 66)
+ if (!dummy_classes[i])
{
- endpost();
- startpost(" ");
- len = 3 + l;
+ int l = 1 + strlen(sl->s_name);
+ if ((len += l) > 66)
+ {
+ endpost();
+ startpost(" ");
+ len = 3 + l;
+ }
+ poststring(sl->s_name);
}
- poststring(sl->s_name);
}
+ endpost();
}
- endpost();
+ else post("no replacement abstractions");
}
-void alldummies_setup(void)
+void dummies_setup(void)
{
t_dummy_slot *sl;
int i;
@@ -606,4 +614,11 @@ void alldummies_setup(void)
(sl->s_nins ? 0 : CLASS_NOINLET), A_GIMME, 0);
}
dummy_nclasses--; /* use "_dummy" as a sentinel */
+
+ ccdummies_class = class_new(gensym("_ccdummies"), 0, 0,
+ sizeof(t_pd), CLASS_PD | CLASS_NOINLET, 0);
+ class_addbang(ccdummies_class, ccdummies_bang);
+ class_addmethod(ccdummies_class, (t_method)ccdummies_reps,
+ gensym("reps"), 0);
+ pd_bind(pd_new(ccdummies_class), gensym("_ccdummies")); /* never freed */
}
diff --git a/cyclone/shadow/shadow.h b/cyclone/shadow/shadow.h
index aefc46e..878a95b 100644
--- a/cyclone/shadow/shadow.h
+++ b/cyclone/shadow/shadow.h
@@ -6,8 +6,5 @@
#define __SHADOW_H__
void allnettles_setup(void);
-void alldummies_setup(void);
-int dummy_nreplacements(void);
-void dummy_printreplacements(char *msg);
#endif
diff --git a/cyclone/sickle/Makefile.sources b/cyclone/sickle/Makefile.sources
index d39cc17..901be5b 100644
--- a/cyclone/sickle/Makefile.sources
+++ b/cyclone/sickle/Makefile.sources
@@ -19,6 +19,7 @@ bitnot.c \
bitor.c \
bitshift.c \
bitxor.c \
+buffir.c \
capture.c \
cartopol.c \
change.c \
diff --git a/cyclone/sickle/Scope.c b/cyclone/sickle/Scope.c
index 8a09d78..adfa51b 100644
--- a/cyclone/sickle/Scope.c
+++ b/cyclone/sickle/Scope.c
@@ -794,7 +794,7 @@ static void scope_vis(t_gobj *z, t_glist *glist, int vis)
if (vis)
{
t_scopehandle *sh = (t_scopehandle *)x->x_handle;
-#ifndef PD_MINOR_VERSION
+#if FORKY_VERSION < 37
rtext_new(glist, t, glist->gl_editor->e_rtext, 0);
#endif
sprintf(sh->h_pathname, ".x%x.h%x", (int)cv, (int)sh);
@@ -805,7 +805,7 @@ static void scope_vis(t_gobj *z, t_glist *glist, int vis)
}
else
{
-#ifndef PD_MINOR_VERSION
+#if FORKY_VERSION < 37
t_rtext *rt = glist_findrtext(glist, t);
if (rt) rtext_free(rt);
#endif
@@ -848,14 +848,7 @@ static t_widgetbehavior scope_widgetbehavior =
scope_delete,
scope_vis,
scope_click,
- /* As of 0.37, pd does not have these last two elements in */
- /* a t_widgetbehavoir anymore. <hans@eds.org> */
-#if PD_MAJOR_VERSION == 0
-#if PD_MINOR_VERSION < 37 || !defined(PD_MINOR_VERSION)
- scope_save,
- 0
-#endif
-#endif
+ FORKY_WIDGETPADDING
};
static void scope_setxymode(t_scope *x, int xymode)
@@ -1040,6 +1033,7 @@ void Scope_tilde_setup(void)
gensym("click"),
A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, A_FLOAT, 0);
class_setwidget(scope_class, &scope_widgetbehavior);
+ forky_setsavefn(scope_class, scope_save);
scopehandle_class = class_new(gensym("_scopehandle"), 0, 0,
sizeof(t_scopehandle), CLASS_PD, 0);
class_addmethod(scopehandle_class, (t_method)scopehandle__clickhook,
diff --git a/cyclone/sickle/allsickles.c b/cyclone/sickle/allsickles.c
index d062c61..7771cf8 100644
--- a/cyclone/sickle/allsickles.c
+++ b/cyclone/sickle/allsickles.c
@@ -20,6 +20,7 @@ void bitnot_tilde_setup(void);
void bitor_tilde_setup(void);
void bitshift_tilde_setup(void);
void bitxor_tilde_setup(void);
+void buffir_tilde_setup(void);
void capture_tilde_setup(void);
void cartopol_tilde_setup(void);
void change_tilde_setup(void);
@@ -98,6 +99,7 @@ void allsickles_setup(void)
bitor_tilde_setup();
bitshift_tilde_setup();
bitxor_tilde_setup();
+ buffir_tilde_setup();
capture_tilde_setup();
cartopol_tilde_setup();
change_tilde_setup();
diff --git a/cyclone/sickle/buffir.c b/cyclone/sickle/buffir.c
new file mode 100644
index 0000000..0551501
--- /dev/null
+++ b/cyclone/sickle/buffir.c
@@ -0,0 +1,213 @@
+/* Copyright (c) 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 <string.h>
+#include "m_pd.h"
+#include "common/loud.h"
+#include "sickle/sic.h"
+#include "sickle/arsic.h"
+
+#define BUFFIR_DEFSIZE 0 /* CHECKED */
+#define BUFFIR_MAXSIZE 128
+
+typedef struct _buffir
+{
+ t_arsic x_arsic;
+ t_pd *x_offinlet;
+ t_pd *x_sizinlet;
+ t_float *x_lohead;
+ t_float *x_hihead;
+ int x_histsize;
+ t_float *x_histlo;
+ t_float *x_histhi;
+ t_float x_histini[2 * BUFFIR_MAXSIZE];
+} t_buffir;
+
+static t_class *buffir_class;
+
+static void buffir_setrange(t_buffir *x, t_floatarg f1, t_floatarg f2)
+{
+ int off = (int)f1;
+ int siz = (int)f2;
+ if (off < 0)
+ off = 0;
+ if (siz <= 0)
+ siz = BUFFIR_DEFSIZE;
+ if (siz > x->x_histsize)
+ {
+ int newsize, pos = x->x_lohead - x->x_histlo;
+ int oldbytes = x->x_histsize * sizeof(*x->x_histlo);
+ static int warned = 0;
+ if (!warned)
+ {
+ loud_incompatible(buffir_class, "stretching history buffer");
+ warned = 1;
+ }
+ newsize = x->x_histsize * 2;
+ while (newsize < siz) newsize *= 2;
+ if (x->x_histlo == x->x_histini)
+ {
+ if (!(x->x_histlo = getbytes(2 * newsize * sizeof(*x->x_histlo))))
+ x->x_histlo = x->x_histini;
+ else
+ {
+ x->x_histhi = x->x_histlo + newsize;
+ memcpy(x->x_histhi + pos - x->x_histsize,
+ x->x_lohead, oldbytes);
+ x->x_lohead = x->x_histlo + pos;
+ x->x_hihead = x->x_histhi + pos;
+ x->x_histsize = newsize;
+ }
+ }
+ else
+ {
+ if (!(x->x_histlo =
+ resizebytes(x->x_histlo, 2 * oldbytes,
+ 2 * newsize * sizeof(*x->x_histlo))))
+ {
+ x->x_histsize = BUFFIR_MAXSIZE;
+ x->x_histlo = x->x_histini;
+ memset(x->x_histlo, 0,
+ 2 * x->x_histsize * sizeof(*x->x_histlo));
+ x->x_lohead = x->x_histlo;
+ x->x_hihead = x->x_histhi = x->x_histlo + x->x_histsize;
+ }
+ else
+ {
+ x->x_histhi = x->x_histlo + newsize;
+ memcpy(x->x_histhi + pos - x->x_histsize,
+ x->x_lohead, oldbytes);
+ x->x_lohead = x->x_histlo + pos;
+ x->x_hihead = x->x_histhi + pos;
+ x->x_histsize = newsize;
+ }
+ }
+ }
+ pd_float(x->x_offinlet, off);
+ pd_float(x->x_sizinlet, siz);
+}
+
+static void buffir_clear(t_buffir *x)
+{
+ memset(x->x_histlo, 0, 2 * x->x_histsize * sizeof(*x->x_histlo));
+ x->x_lohead = x->x_histlo;
+ x->x_hihead = x->x_histhi = x->x_histlo + x->x_histsize;
+}
+
+static void buffir_set(t_buffir *x, t_symbol *s, t_floatarg f1, t_floatarg f2)
+{
+ arsic_setarray((t_arsic *)x, s, 1);
+ buffir_setrange(x, f1, f2);
+}
+
+static t_int *buffir_perform(t_int *w)
+{
+ t_arsic *sic = (t_arsic *)(w[1]);
+ t_buffir *x = (t_buffir *)sic;
+ int nblock = (int)(w[2]);
+ t_float *xin = (t_float *)(w[3]);
+ t_float *out = (t_float *)(w[6]);
+ t_float *lohead = x->x_lohead;
+ t_float *hihead = x->x_hihead;
+ if (sic->s_playable)
+ {
+ t_float *oin = (t_float *)(w[4]);
+ t_float *sin = (t_float *)(w[5]);
+ int vecsize = sic->s_vecsize;
+ t_float *vec = sic->s_vectors[0]; /* playable implies nonzero (mono) */
+ int histsize = x->x_histsize;
+ while (nblock--)
+ {
+ /* CHECKME every sample or once per block.
+ If once per block, then LATER think about performance. */
+ /* CHECKME rounding */
+ int off = (int)*oin++;
+ int npoints = (int)*sin++;
+ if (off < 0)
+ off = 0;
+ if (npoints > histsize)
+ npoints = histsize;
+ if (npoints > vecsize - off)
+ npoints = vecsize - off;
+ if (npoints > 0)
+ {
+ t_float *coefp = vec + off;
+ t_float *hp = hihead;
+ t_float sum = 0.;
+ *lohead++ = *hihead++ = *xin++;
+ while (npoints--)
+ sum += *coefp++ * *hp--;
+ *out++ = sum;
+ }
+ else
+ {
+ *lohead++ = *hihead++ = *xin++;
+ *out++ = 0.;
+ }
+ if (lohead >= x->x_histhi)
+ {
+ lohead = x->x_histlo;
+ hihead = x->x_histhi;
+ }
+ }
+ }
+ else while (nblock--)
+ {
+ *lohead++ = *hihead++ = *xin++;
+ *out++ = 0.;
+ if (lohead >= x->x_histhi)
+ {
+ lohead = x->x_histlo;
+ hihead = x->x_histhi;
+ }
+ }
+ x->x_lohead = lohead;
+ x->x_hihead = hihead;
+ return (w + 7);
+}
+
+static void buffir_dsp(t_buffir *x, t_signal **sp)
+{
+ arsic_dsp((t_arsic *)x, sp, buffir_perform, 1);
+}
+
+static void buffir_free(t_buffir *x)
+{
+ if (x->x_histlo != x->x_histini)
+ freebytes(x->x_histlo, 2 * x->x_histsize * sizeof(*x->x_histlo));
+ arsic_free((t_arsic *)x);
+}
+
+static void *buffir_new(t_symbol *s, t_floatarg f1, t_floatarg f2)
+{
+ /* CHECKME always the first channel used. */
+ /* three auxiliary signals: main, offset and size inputs */
+ t_buffir *x = (t_buffir *)arsic_new(buffir_class, s, 0, 0, 3);
+ if (x)
+ {
+ arsic_setminsize((t_arsic *)x, 1);
+ x->x_offinlet = (t_pd *)sic_newinlet((t_sic *)x, f1);
+ x->x_sizinlet = (t_pd *)sic_newinlet((t_sic *)x, f2);
+ outlet_new((t_object *)x, &s_signal);
+ x->x_histsize = BUFFIR_MAXSIZE;
+ x->x_histlo = x->x_histini;
+ buffir_clear(x);
+ buffir_setrange(x, f1, f2);
+ }
+ return (x);
+}
+
+void buffir_tilde_setup(void)
+{
+ buffir_class = class_new(gensym("buffir~"),
+ (t_newmethod)buffir_new,
+ (t_method)buffir_free,
+ sizeof(t_buffir), 0,
+ A_DEFSYM, A_DEFFLOAT, A_DEFFLOAT, 0);
+ arsic_setup(buffir_class, buffir_dsp, SIC_FLOATTOSIGNAL);
+ class_addmethod(buffir_class, (t_method)buffir_clear,
+ gensym("clear"), 0);
+ class_addmethod(buffir_class, (t_method)buffir_set,
+ gensym("set"), A_SYMBOL, A_DEFFLOAT, A_DEFFLOAT, 0);
+}