summaryrefslogtreecommitdiff
path: root/apps/plugins/pdbox/PDa/intern/bp~.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/bp~.c')
-rw-r--r--apps/plugins/pdbox/PDa/intern/bp~.c276
1 files changed, 276 insertions, 0 deletions
diff --git a/apps/plugins/pdbox/PDa/intern/bp~.c b/apps/plugins/pdbox/PDa/intern/bp~.c
new file mode 100644
index 0000000000..f247c1d66b
--- /dev/null
+++ b/apps/plugins/pdbox/PDa/intern/bp~.c
@@ -0,0 +1,276 @@
1#include <m_pd.h>
2#include <m_fixed.h>
3
4typedef struct bpctl
5{
6 t_sample c_x1;
7 t_sample c_x2;
8 t_sample c_coef1;
9 t_sample c_coef2;
10 t_sample c_gain;
11} t_bpctl;
12
13typedef struct sigbp
14{
15 t_object x_obj;
16 float x_sr;
17 float x_freq;
18 float x_q;
19 t_bpctl x_cspace;
20 t_bpctl *x_ctl;
21 float x_f;
22} t_sigbp;
23
24t_class *sigbp_class;
25
26static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q);
27
28static void *sigbp_new(t_floatarg f, t_floatarg q)
29{
30 t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
31 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
32 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
33 outlet_new(&x->x_obj, gensym("signal"));
34 x->x_sr = 44100;
35 x->x_ctl = &x->x_cspace;
36 x->x_cspace.c_x1 = 0;
37 x->x_cspace.c_x2 = 0;
38 sigbp_docoef(x, f, q);
39 x->x_f = 0;
40 return (x);
41}
42
43static float sigbp_qcos(float f)
44{
45 if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
46 {
47 float g = f*f;
48 return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
49 }
50 else return (0);
51}
52
53static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
54{
55 float r, oneminusr, omega;
56 if (f < 0.001) f = 10;
57 if (q < 0) q = 0;
58 x->x_freq = f;
59 x->x_q = q;
60 omega = f * (2.0f * 3.14159f) / x->x_sr;
61 if (q < 0.001) oneminusr = 1.0f;
62 else oneminusr = omega/q;
63 if (oneminusr > 1.0f) oneminusr = 1.0f;
64 r = 1.0f - oneminusr;
65 x->x_ctl->c_coef1 = ftofix(2.0f * sigbp_qcos(omega) * r);
66 x->x_ctl->c_coef2 = ftofix(- r * r);
67 x->x_ctl->c_gain = ftofix(2 * oneminusr * (oneminusr + r * omega));
68 /* post("r %f, omega %f, coef1 %f, coef2 %f",
69 r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
70}
71
72static void sigbp_ft1(t_sigbp *x, t_floatarg f)
73{
74 sigbp_docoef(x, f, x->x_q);
75}
76
77static void sigbp_ft2(t_sigbp *x, t_floatarg q)
78{
79 sigbp_docoef(x, x->x_freq, q);
80}
81
82static void sigbp_clear(t_sigbp *x, t_floatarg q)
83{
84 x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0;
85}
86
87static t_int *sigbp_perform(t_int *w)
88{
89 t_sample *in = (t_sample *)(w[1]);
90 t_sample *out = (t_sample *)(w[2]);
91 t_bpctl *c = (t_bpctl *)(w[3]);
92 int n = (t_int)(w[4]);
93 int i;
94 t_sample last = c->c_x1;
95 t_sample prev = c->c_x2;
96 t_sample coef1 = c->c_coef1;
97 t_sample coef2 = c->c_coef2;
98 t_sample gain = c->c_gain;
99 for (i = 0; i < n; i++)
100 {
101 t_sample output = *in++ + mult(coef1,last) + mult(coef2,prev);
102 *out++ = mult(gain,output);
103 prev = last;
104 last = output;
105 }
106 if (PD_BADFLOAT(last))
107 last = 0;
108 if (PD_BADFLOAT(prev))
109 prev = 0;
110 c->c_x1 = last;
111 c->c_x2 = prev;
112 return (w+5);
113}
114
115static void sigbp_dsp(t_sigbp *x, t_signal **sp)
116{
117 x->x_sr = sp[0]->s_sr;
118 sigbp_docoef(x, x->x_freq, x->x_q);
119 dsp_add(sigbp_perform, 4,
120 sp[0]->s_vec, sp[1]->s_vec,
121 x->x_ctl, sp[0]->s_n);
122
123}
124
125void bp_tilde_setup(void)
126{
127 sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
128 sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
129 CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
130 class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
131 class_addmethod(sigbp_class, (t_method)sigbp_ft1,
132 gensym("ft1"), A_FLOAT, 0);
133 class_addmethod(sigbp_class, (t_method)sigbp_ft2,
134 gensym("ft2"), A_FLOAT, 0);
135 class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
136 class_sethelpsymbol(sigbp_class, gensym("lop~-help.pd"));
137}
138
139#include <m_pd.h>
140#include <m_fixed.h>
141
142typedef struct bpctl
143{
144 t_sample c_x1;
145 t_sample c_x2;
146 t_sample c_coef1;
147 t_sample c_coef2;
148 t_sample c_gain;
149} t_bpctl;
150
151typedef struct sigbp
152{
153 t_object x_obj;
154 float x_sr;
155 float x_freq;
156 float x_q;
157 t_bpctl x_cspace;
158 t_bpctl *x_ctl;
159 float x_f;
160} t_sigbp;
161
162t_class *sigbp_class;
163
164static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q);
165
166static void *sigbp_new(t_floatarg f, t_floatarg q)
167{
168 t_sigbp *x = (t_sigbp *)pd_new(sigbp_class);
169 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft1"));
170 inlet_new(&x->x_obj, &x->x_obj.ob_pd, gensym("float"), gensym("ft2"));
171 outlet_new(&x->x_obj, gensym("signal"));
172 x->x_sr = 44100;
173 x->x_ctl = &x->x_cspace;
174 x->x_cspace.c_x1 = 0;
175 x->x_cspace.c_x2 = 0;
176 sigbp_docoef(x, f, q);
177 x->x_f = 0;
178 return (x);
179}
180
181static float sigbp_qcos(float f)
182{
183 if (f >= -(0.5f*3.14159f) && f <= 0.5f*3.14159f)
184 {
185 float g = f*f;
186 return (((g*g*g * (-1.0f/720.0f) + g*g*(1.0f/24.0f)) - g*0.5) + 1);
187 }
188 else return (0);
189}
190
191static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q)
192{
193 float r, oneminusr, omega;
194 if (f < 0.001) f = 10;
195 if (q < 0) q = 0;
196 x->x_freq = f;
197 x->x_q = q;
198 omega = f * (2.0f * 3.14159f) / x->x_sr;
199 if (q < 0.001) oneminusr = 1.0f;
200 else oneminusr = omega/q;
201 if (oneminusr > 1.0f) oneminusr = 1.0f;
202 r = 1.0f - oneminusr;
203 x->x_ctl->c_coef1 = ftofix(2.0f * sigbp_qcos(omega) * r);
204 x->x_ctl->c_coef2 = ftofix(- r * r);
205 x->x_ctl->c_gain = ftofix(2 * oneminusr * (oneminusr + r * omega));
206 /* post("r %f, omega %f, coef1 %f, coef2 %f",
207 r, omega, x->x_ctl->c_coef1, x->x_ctl->c_coef2); */
208}
209
210static void sigbp_ft1(t_sigbp *x, t_floatarg f)
211{
212 sigbp_docoef(x, f, x->x_q);
213}
214
215static void sigbp_ft2(t_sigbp *x, t_floatarg q)
216{
217 sigbp_docoef(x, x->x_freq, q);
218}
219
220static void sigbp_clear(t_sigbp *x, t_floatarg q)
221{
222 x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0;
223}
224
225static t_int *sigbp_perform(t_int *w)
226{
227 t_sample *in = (t_sample *)(w[1]);
228 t_sample *out = (t_sample *)(w[2]);
229 t_bpctl *c = (t_bpctl *)(w[3]);
230 int n = (t_int)(w[4]);
231 int i;
232 t_sample last = c->c_x1;
233 t_sample prev = c->c_x2;
234 t_sample coef1 = c->c_coef1;
235 t_sample coef2 = c->c_coef2;
236 t_sample gain = c->c_gain;
237 for (i = 0; i < n; i++)
238 {
239 t_sample output = *in++ + mult(coef1,last) + mult(coef2,prev);
240 *out++ = mult(gain,output);
241 prev = last;
242 last = output;
243 }
244 if (PD_BADFLOAT(last))
245 last = 0;
246 if (PD_BADFLOAT(prev))
247 prev = 0;
248 c->c_x1 = last;
249 c->c_x2 = prev;
250 return (w+5);
251}
252
253static void sigbp_dsp(t_sigbp *x, t_signal **sp)
254{
255 x->x_sr = sp[0]->s_sr;
256 sigbp_docoef(x, x->x_freq, x->x_q);
257 dsp_add(sigbp_perform, 4,
258 sp[0]->s_vec, sp[1]->s_vec,
259 x->x_ctl, sp[0]->s_n);
260
261}
262
263void bp_tilde_setup(void)
264{
265 sigbp_class = class_new(gensym("bp~"), (t_newmethod)sigbp_new, 0,
266 sizeof(t_sigbp), 0, A_DEFFLOAT, A_DEFFLOAT, 0);
267 CLASS_MAINSIGNALIN(sigbp_class, t_sigbp, x_f);
268 class_addmethod(sigbp_class, (t_method)sigbp_dsp, gensym("dsp"), 0);
269 class_addmethod(sigbp_class, (t_method)sigbp_ft1,
270 gensym("ft1"), A_FLOAT, 0);
271 class_addmethod(sigbp_class, (t_method)sigbp_ft2,
272 gensym("ft2"), A_FLOAT, 0);
273 class_addmethod(sigbp_class, (t_method)sigbp_clear, gensym("clear"), 0);
274 class_sethelpsymbol(sigbp_class, gensym("lop~-help.pd"));
275}
276