1
by Hans-Christoph Steiner
Import upstream version 0.12.1 |
1 |
#include "defines.h" |
2 |
||
3 |
/*--------------- deltas ---------------*/
|
|
4 |
||
5 |
static t_class *deltas_class; |
|
6 |
||
7 |
typedef struct _deltas |
|
8 |
{
|
|
9 |
t_object x_obj; |
|
10 |
float m_lo; |
|
11 |
float m_hi; |
|
12 |
int m_buffer_size; |
|
13 |
int m_buffer_index; |
|
14 |
float *m_buffer; // circular buffer |
|
15 |
} t_deltas; |
|
16 |
||
17 |
||
18 |
static void deltas_perform_float(t_deltas *x, t_float f) |
|
19 |
{
|
|
20 |
int index; |
|
21 |
index=x->m_buffer_index+1; |
|
22 |
index=(index==x->m_buffer_size)?0:index; |
|
23 |
x->m_buffer_index=index; |
|
24 |
x->m_buffer[index]=f; |
|
25 |
}
|
|
26 |
||
27 |
static void deltas_bang(t_deltas *x) |
|
28 |
{
|
|
29 |
int lo,hi,n,index,size; |
|
30 |
t_atom *ap,*app; |
|
31 |
float last; |
|
32 |
float *buffer, *bp; |
|
33 |
||
34 |
lo=(int)x->m_lo; |
|
35 |
hi=(int)x->m_hi; |
|
36 |
||
37 |
n=hi-lo; |
|
38 |
size=x->m_buffer_size; |
|
39 |
index=x->m_buffer_index; |
|
40 |
ap = (t_atom *)getbytes(sizeof(t_atom)*n); |
|
41 |
app=ap; |
|
42 |
buffer=x->m_buffer; |
|
43 |
last=buffer[index]; |
|
44 |
bp=buffer+index-lo; |
|
45 |
bp=(bp>=buffer)?bp:bp+size; // wrap |
|
46 |
||
47 |
if (bp-buffer>=n) |
|
48 |
{ // no wrap-around needed |
|
49 |
index=n; |
|
50 |
while(index--){ |
|
51 |
SETFLOAT(app, last-*bp--); |
|
52 |
app++; |
|
53 |
}
|
|
54 |
// post("not wrapped, app-ap=%i",app-ap);
|
|
55 |
}
|
|
56 |
else // need to wrap |
|
57 |
{
|
|
58 |
int ps, nn; |
|
59 |
ps = bp-buffer; |
|
60 |
nn=n; |
|
61 |
// post(" nn=%i",nn);
|
|
62 |
for(;ps>=0;ps--) // don't we miss one sample in signal??? |
|
63 |
{
|
|
64 |
// post("ps=%i",ps);
|
|
65 |
SETFLOAT(app, last-buffer[ps]); |
|
66 |
app++; |
|
67 |
nn--; |
|
68 |
}
|
|
69 |
ps=size-1; |
|
70 |
// post(" nn=%i",nn);
|
|
71 |
for(;nn>0;nn--) |
|
72 |
{
|
|
73 |
// post("ps=%i",ps);
|
|
74 |
SETFLOAT(app, last-buffer[ps--]); |
|
75 |
app++; |
|
76 |
}
|
|
77 |
||
78 |
/*
|
|
79 |
int i2;
|
|
80 |
index=bp-buffer;
|
|
81 |
i2=index;
|
|
82 |
post("first part %i",index);
|
|
83 |
while(index--){
|
|
84 |
SETFLOAT(app, last-*bp--);
|
|
85 |
app++;
|
|
86 |
}
|
|
87 |
index=n-i2;
|
|
88 |
post("2nd part %i",index);
|
|
89 |
bp=buffer+size-1;
|
|
90 |
while(index--){
|
|
91 |
SETFLOAT(app, last-*bp--);
|
|
92 |
app++;
|
|
93 |
}
|
|
94 |
*/
|
|
95 |
// post("wrapped, app-ap=%i",app-ap);
|
|
96 |
}
|
|
97 |
||
98 |
outlet_list(x->x_obj.ob_outlet,gensym("list"),n,ap); |
|
99 |
freebytes(ap, sizeof(t_atom)*n); |
|
100 |
}
|
|
101 |
||
102 |
static void deltas_clear(t_deltas *x) |
|
103 |
{
|
|
104 |
int i,s; |
|
105 |
float *f; |
|
106 |
f=x->m_buffer; |
|
107 |
s=x->m_buffer_size; |
|
108 |
for (i=0;i<s;i++) |
|
109 |
*f++=0.0f; |
|
110 |
}
|
|
111 |
||
112 |
static void deltas_set(t_deltas *x, t_float lo, t_float hi, t_float size) |
|
113 |
{
|
|
114 |
if (size<1) |
|
115 |
{
|
|
116 |
size=1; |
|
117 |
post("deltas: size is minimum 1..."); |
|
118 |
}
|
|
119 |
if (hi>size) |
|
120 |
{
|
|
121 |
post("deltas: higher bound cannot be higher than the buffer size..."); |
|
122 |
hi=size; |
|
123 |
}
|
|
124 |
if (lo<0) |
|
125 |
{
|
|
126 |
post("deltas: lower bound cannot be negative..."); |
|
127 |
lo=0; |
|
128 |
}
|
|
129 |
if (hi<1) |
|
130 |
{
|
|
131 |
post("deltas: higher bound cannot be smaller than one..."); |
|
132 |
hi=1; |
|
133 |
}
|
|
134 |
if (hi<=lo) |
|
135 |
{
|
|
136 |
post("deltas: higher bound must be higher than lower bound..."); |
|
137 |
lo=hi-1.0f; |
|
138 |
}
|
|
139 |
||
140 |
freebytes(x->m_buffer, x->m_buffer_size); |
|
141 |
||
142 |
x->m_hi=(float)((int)hi); |
|
143 |
x->m_lo=(float)((int)lo); |
|
144 |
x->m_buffer_size=(int)size; |
|
145 |
x->m_buffer = (float*)getbytes(sizeof(float)*x->m_buffer_size); |
|
146 |
deltas_clear(x); |
|
147 |
x->m_buffer_index=0; |
|
148 |
}
|
|
149 |
||
150 |
static void *deltas_new(t_float lo, t_float hi, t_float size) |
|
151 |
{
|
|
152 |
t_deltas *x=(t_deltas *)pd_new(deltas_class); |
|
153 |
outlet_new(&x->x_obj, gensym("list")); |
|
154 |
x->m_buffer_size=0; |
|
155 |
x->m_buffer=0; |
|
156 |
deltas_set(x, lo, hi, size); |
|
157 |
||
158 |
floatinlet_new(&x->x_obj, &x->m_lo); |
|
159 |
floatinlet_new(&x->x_obj, &x->m_hi); |
|
160 |
||
161 |
return (void *)x; |
|
162 |
}
|
|
163 |
||
164 |
static void deltas_free(t_deltas *x) |
|
165 |
{
|
|
166 |
freebytes(x->m_buffer, x->m_buffer_size); |
|
167 |
}
|
|
168 |
||
169 |
void deltas_setup(void) |
|
170 |
{
|
|
171 |
deltas_class = class_new(gensym("deltas"), |
|
172 |
(t_newmethod)deltas_new, (t_method)deltas_free, |
|
173 |
sizeof(t_deltas), |
|
174 |
CLASS_DEFAULT, |
|
175 |
A_DEFFLOAT, A_DEFFLOAT, A_DEFFLOAT,0); |
|
176 |
||
177 |
class_addmethod(deltas_class, (t_method)deltas_clear, gensym("clear"),0); |
|
178 |
class_addfloat(deltas_class, (t_method)deltas_perform_float); |
|
179 |
class_addbang(deltas_class, (t_method)deltas_bang); |
|
180 |
}
|
|
181 |