Max 5 API Reference
00001 /** 00002 @file 00003 index~ - SDK example of an object which accesses an MSP buffer~ 00004 00005 updated 3/22/09 ajm: new API 00006 00007 @ingroup examples 00008 */ 00009 00010 #include "ext.h" 00011 #include "ext_obex.h" 00012 #include "ext_common.h" // contains CLIP macro 00013 #include "z_dsp.h" 00014 #include "buffer.h" // this defines our buffer's data structure and other goodies 00015 #include "ext_atomic.h" 00016 00017 void *index_class; 00018 00019 typedef struct _index 00020 { 00021 t_pxobject l_obj; 00022 t_symbol *l_sym; 00023 t_buffer *l_buf; 00024 long l_chan; 00025 } t_index; 00026 00027 t_int *index_perform(t_int *w); 00028 void index_dsp(t_index *x, t_signal **sp); 00029 void index_set(t_index *x, t_symbol *s); 00030 void *index_new(t_symbol *s, long chan); 00031 void index_in1(t_index *x, long n); 00032 void index_assist(t_index *x, void *b, long m, long a, char *s); 00033 void index_dblclick(t_index *x); 00034 00035 t_symbol *ps_buffer; 00036 00037 int main(void) 00038 { 00039 t_class *c; 00040 00041 c = class_new("index~", (method)index_new, (method)dsp_free, (short)sizeof(t_index), 0L, 00042 A_SYM, A_DEFLONG, 0); 00043 class_addmethod(c, (method)index_dsp, "dsp", A_CANT, 0); 00044 class_addmethod(c, (method)index_set, "set", A_SYM, 0); 00045 class_addmethod(c, (method)index_in1, "in1", A_LONG, 0); 00046 class_addmethod(c, (method)index_assist, "assist", A_CANT, 0); 00047 class_addmethod(c, (method)index_dblclick, "dblclick", A_CANT, 0); 00048 class_dspinit(c); 00049 class_register(CLASS_BOX, c); 00050 index_class = c; 00051 00052 ps_buffer = gensym("buffer~"); 00053 00054 return 0; 00055 } 00056 00057 00058 t_int *index_perform(t_int *w) 00059 { 00060 t_index *x = (t_index *)(w[1]); 00061 t_float *in = (t_float *)(w[2]); 00062 t_float *out = (t_float *)(w[3]); 00063 int n = (int)(w[4]); 00064 t_buffer *b = x->l_buf; 00065 float *tab; 00066 double temp; 00067 double f; 00068 long index,chan,frames,nc; 00069 00070 if (x->l_obj.z_disabled) 00071 goto out; 00072 if (!b) 00073 goto zero; 00074 ATOMIC_INCREMENT(&b->b_inuse); 00075 if (!b->b_valid) { 00076 ATOMIC_DECREMENT(&b->b_inuse); 00077 goto zero; 00078 } 00079 tab = b->b_samples; 00080 chan = x->l_chan; 00081 frames = b->b_frames; 00082 nc = b->b_nchans; 00083 while (n--) { 00084 temp = *in++; 00085 f = temp + 0.5; 00086 index = f; 00087 if (index < 0) 00088 index = 0; 00089 else if (index >= frames) 00090 index = frames - 1; 00091 if (nc > 1) 00092 index = index * nc + chan; 00093 *out++ = tab[index]; 00094 } 00095 ATOMIC_DECREMENT(&b->b_inuse); 00096 return w + 5; 00097 zero: 00098 while (n--) *out++ = 0.; 00099 out: 00100 return w + 5; 00101 } 00102 00103 // here's where we set the buffer~ we're going to access 00104 void index_set(t_index *x, t_symbol *s) 00105 { 00106 t_buffer *b; 00107 00108 if (s) { 00109 x->l_sym = s; 00110 if ((b = (t_buffer *)(s->s_thing)) && ob_sym(b) == ps_buffer) { 00111 x->l_buf = b; 00112 } else { 00113 object_error((t_object *)x, "no buffer~ %s", s->s_name); 00114 x->l_buf = 0; 00115 } 00116 } else { 00117 // this will reappear every time the dsp is restarted; do we really want it? 00118 object_error((t_object *)x, "no buffer~ object specified"); 00119 } 00120 } 00121 00122 void index_in1(t_index *x, long n) 00123 { 00124 if (n) 00125 x->l_chan = CLIP(n,1,4) - 1; 00126 else 00127 x->l_chan = 0; 00128 } 00129 00130 void index_dsp(t_index *x, t_signal **sp) 00131 { 00132 index_set(x,x->l_sym); 00133 dsp_add(index_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); 00134 } 00135 00136 // this lets us double-click on index~ to open up the buffer~ it references 00137 void index_dblclick(t_index *x) 00138 { 00139 t_buffer *b; 00140 00141 if ((b = (t_buffer *)(x->l_sym->s_thing)) && ob_sym(b) == ps_buffer) 00142 mess0((t_object *)b,gensym("dblclick")); 00143 } 00144 00145 void index_assist(t_index *x, void *b, long m, long a, char *s) 00146 { 00147 if (m == ASSIST_OUTLET) 00148 sprintf(s,"(signal) Sample Value at Index"); 00149 else { 00150 switch (a) { 00151 case 0: sprintf(s,"(signal) Sample Index"); break; 00152 case 1: sprintf(s,"Audio Channel In buffer~"); break; 00153 } 00154 } 00155 } 00156 00157 void *index_new(t_symbol *s, long chan) 00158 { 00159 t_index *x = object_alloc(index_class); 00160 dsp_setup((t_pxobject *)x, 1); 00161 intin((t_object *)x,1); 00162 outlet_new((t_object *)x, "signal"); 00163 x->l_sym = s; 00164 index_in1(x,chan); 00165 return (x); 00166 } 00167
Copyright © 2008, Cycling '74