diff options
Diffstat (limited to 'apps/plugins/pdbox/PDa/intern/bp~.c')
-rw-r--r-- | apps/plugins/pdbox/PDa/intern/bp~.c | 276 |
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 | |||
4 | typedef 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 | |||
13 | typedef 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 | |||
24 | t_class *sigbp_class; | ||
25 | |||
26 | static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q); | ||
27 | |||
28 | static 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 | |||
43 | static 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 | |||
53 | static 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 | |||
72 | static void sigbp_ft1(t_sigbp *x, t_floatarg f) | ||
73 | { | ||
74 | sigbp_docoef(x, f, x->x_q); | ||
75 | } | ||
76 | |||
77 | static void sigbp_ft2(t_sigbp *x, t_floatarg q) | ||
78 | { | ||
79 | sigbp_docoef(x, x->x_freq, q); | ||
80 | } | ||
81 | |||
82 | static void sigbp_clear(t_sigbp *x, t_floatarg q) | ||
83 | { | ||
84 | x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0; | ||
85 | } | ||
86 | |||
87 | static 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 | |||
115 | static 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 | |||
125 | void 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 | |||
142 | typedef 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 | |||
151 | typedef 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 | |||
162 | t_class *sigbp_class; | ||
163 | |||
164 | static void sigbp_docoef(t_sigbp *x, t_floatarg f, t_floatarg q); | ||
165 | |||
166 | static 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 | |||
181 | static 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 | |||
191 | static 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 | |||
210 | static void sigbp_ft1(t_sigbp *x, t_floatarg f) | ||
211 | { | ||
212 | sigbp_docoef(x, f, x->x_q); | ||
213 | } | ||
214 | |||
215 | static void sigbp_ft2(t_sigbp *x, t_floatarg q) | ||
216 | { | ||
217 | sigbp_docoef(x, x->x_freq, q); | ||
218 | } | ||
219 | |||
220 | static void sigbp_clear(t_sigbp *x, t_floatarg q) | ||
221 | { | ||
222 | x->x_ctl->c_x1 = x->x_ctl->c_x2 = 0; | ||
223 | } | ||
224 | |||
225 | static 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 | |||
253 | static 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 | |||
263 | void 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 | |||