~ubuntu-branches/ubuntu/precise/pd-smlib/precise

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