Commit | Line | Data |
---|---|---|
21c4e167 H |
1 | #include "m_pd.h" |
2 | #ifdef NT | |
3 | #pragma warning( disable : 4244 ) | |
4 | #pragma warning( disable : 4305 ) | |
5 | #endif | |
6 | ||
7 | /* ------------------------ dspobj~ ----------------------------- */ | |
8 | ||
9 | /* tilde object to take absolute value. */ | |
10 | ||
11 | static t_class *dspobj_class; | |
12 | ||
13 | typedef struct _dspobj | |
14 | { | |
15 | t_object x_obj; /* obligatory header */ | |
16 | t_float x_f; /* place to hold inlet's value if it's set by message */ | |
17 | } t_dspobj; | |
18 | ||
19 | /* this is the actual performance routine which acts on the samples. | |
20 | It's called with a single pointer "w" which is our location in the | |
21 | DSP call list. We return a new "w" which will point to the next item | |
22 | after us. Meanwhile, w[0] is just a pointer to dsp-perform itself | |
23 | (no use to us), w[1] and w[2] are the input and output vector locations, | |
24 | and w[3] is the number of points to calculate. */ | |
25 | static t_int *dspobj_perform(t_int *w) | |
26 | { | |
27 | t_float *in = (t_float *)(w[1]); | |
28 | t_float *out = (t_float *)(w[2]); | |
29 | int n = (int)(w[3]); | |
30 | while (n--) | |
31 | { | |
32 | float f = *(in++); | |
33 | *out++ = (f > 0 ? f : -f); | |
34 | } | |
35 | return (w+4); | |
36 | } | |
37 | ||
38 | /* called to start DSP. Here we call Pd back to add our perform | |
39 | routine to a linear callback list which Pd in turn calls to grind | |
40 | out the samples. */ | |
41 | static void dspobj_dsp(t_dspobj *x, t_signal **sp) | |
42 | { | |
43 | dsp_add(dspobj_perform, 3, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); | |
44 | } | |
45 | ||
46 | static void *dspobj_new(void) | |
47 | { | |
48 | t_dspobj *x = (t_dspobj *)pd_new(dspobj_class); | |
49 | outlet_new(&x->x_obj, gensym("signal")); | |
50 | x->x_f = 0; | |
51 | return (x); | |
52 | } | |
53 | ||
54 | /* this routine, which must have exactly this name (with the "~" replaced | |
55 | by "_tilde) is called when the code is first loaded, and tells Pd how | |
56 | to build the "class". */ | |
57 | void dspobj_tilde_setup(void) | |
58 | { | |
59 | dspobj_class = class_new(gensym("dspobj~"), (t_newmethod)dspobj_new, 0, | |
60 | sizeof(t_dspobj), 0, A_DEFFLOAT, 0); | |
61 | /* this is magic to declare that the leftmost, "main" inlet | |
62 | takes signals; other signal inlets are done differently... */ | |
63 | CLASS_MAINSIGNALIN(dspobj_class, t_dspobj, x_f); | |
64 | /* here we tell Pd about the "dsp" method, which is called back | |
65 | when DSP is turned on. */ | |
66 | class_addmethod(dspobj_class, (t_method)dspobj_dsp, gensym("dsp"), 0); | |
67 | } |