1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
/* 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. */
/* generic signal class */
#include <math.h>
#include "m_pd.h"
#include "shared.h"
#include "common/loud.h"
#include "sickle/sic.h"
#ifdef KRZYSZCZ
//#define SIC_DEBUG
#endif
#if defined(_WIN32) || defined(MACOSX)
/* cf pd/src/x_arithmetic.c */
#define cosf cos
#endif
t_inlet *sic_inlet(t_sic *x, int ix, t_float df, int ax, int ac, t_atom *av)
{
t_inlet *in = 0;
if (ax < ac)
{
if (av[ax].a_type == A_FLOAT)
df = av[ax].a_w.w_float;
else
loud_error((t_pd *)x, "bad argument %d (float expected)", ax + 1);
}
if (ix)
{
in = inlet_new((t_object *)x, (t_pd *)x, &s_signal, &s_signal);
/* this is persistent (in->i_un.iu_floatsignalvalue = df) */
pd_float((t_pd *)in, df);
}
else
{
in = ((t_object *)x)->ob_inlet;
pd_float((t_pd *)x, df);
}
return (in);
}
t_inlet *sic_newinlet(t_sic *x, t_float f)
{
return (sic_inlet(x, 1, f, 0, 0, 0));
}
t_float *sic_makecostable(int *sizep)
{
/* permanent cache (tables are never freed); LATER rethink */
static t_float *sic_costables[SIC_NCOSTABLES];
int ndx, sz;
/* round upwards -- always return at least requested number of elements,
unless the maximum of 2^SIC_NCOSTABLES is exceeded; LATER rethink */
/* (the minimum, at ndx 0, is 2^1) */
for (ndx = 0, sz = 2; ndx < (SIC_NCOSTABLES - 1); ndx++, sz <<= 1)
if (sz >= *sizep)
break;
#ifdef SIC_DEBUG
loudbug_post("request for a costable of %d points (effective %d, ndx %d)",
*sizep, sz, ndx);
#endif
*sizep = sz;
if (sic_costables[ndx])
return (sic_costables[ndx]);
else if (sz == COSTABSIZE && cos_table)
return (sic_costables[ndx] = cos_table);
else
{
int cnt = sz + 1;
float phase = 0, phsinc = SHARED_2PI / sz;
t_float *table = (t_float *)getbytes(cnt * sizeof(*table)), *tp = table;
if (table)
{
#ifdef SIC_DEBUG
loudbug_post("got %d points of a costable", cnt);
#endif
while (cnt--)
{
*tp++ = cosf(phase);
phase += phsinc;
}
}
return (sic_costables[ndx] = table);
}
}
static void sic_enable(t_sic *x, t_floatarg f)
{
x->s_disabled = (f == 0);
}
void sic_setup(t_class *c, void *dspfn, void *floatfn)
{
static int checked = 0;
if (!checked)
{
/* MSP: here we check at startup whether the byte alignment
is as we declared it. If not, the code has to be
recompiled the other way. */
t_shared_wrappy wrappy;
wrappy.w_d = SHARED_UNITBIT32 + 0.5;
if ((unsigned)wrappy.w_i[SHARED_LOWOFFSET] != 0x80000000)
loudbug_bug("sic_setup: unexpected machine alignment");
checked = 1;
}
if (floatfn != SIC_NOMAINSIGNALIN)
{
if (floatfn)
{
class_domainsignalin(c, -1);
class_addfloat(c, floatfn);
}
else CLASS_MAINSIGNALIN(c, t_sic, s_f);
}
class_addmethod(c, (t_method)dspfn, gensym("dsp"), 0);
class_addmethod(c, (t_method)sic_enable, gensym("enable"), 0);
}
|