Max 5 API Reference
00001 // z_dsp.h -- the main header file for all DSP objects copyright 1997-2003 Cycling '74 00002 00003 // DSP services: 00004 00005 #ifndef _Z_DSP_H 00006 #define _Z_DSP_H 00007 00008 #ifndef SAMPLE_TYPEDEF 00009 /** An integer. @ingroup msp */ 00010 typedef int t_int; 00011 /** A float. @ingroup msp */ 00012 typedef float t_float; 00013 /** A sample value. @ingroup msp */ 00014 typedef float t_sample; 00015 #define SAMPLE_TYPEDEF 00016 #endif 00017 00018 #include "z_altivec.h" 00019 #include "ext_systhread.h" 00020 00021 #if C74_PRAGMA_STRUCT_PACKPUSH 00022 #pragma pack(push, 2) 00023 #elif C74_PRAGMA_STRUCT_PACK 00024 #pragma pack(2) 00025 #endif 00026 00027 /** MSP System Properties. 00028 @ingroup msp */ 00029 enum { 00030 SYS_MAXBLKSIZE = 2048, ///< a good number for a maximum signal vector size 00031 SYS_MAXSIGS = 250 ///< number of signal inlets you can have in an object 00032 }; 00033 00034 // macro loop for checking for NAN/INF 00035 00036 // note: this may be platform-dependent 00037 00038 #define NAN_MASK 0x7F800000 00039 00040 #define NAN_CHECK(n,o) \ 00041 while (n--) { if ((*(o) & NAN_MASK) == NAN_MASK) *(o) = 0; (o)++; } // now post inc/dec -Rd jun 05 00042 00043 #define IS_DENORM_FLOAT(v) ((((*(unsigned long *)&(v))&0x7f800000)==0)&&((v)!=0.f)) 00044 #define IS_DENORM_DOUBLE(v) ((((((unsigned long *)&(v))[1])&0x7fe00000)==0)&&((v)!=0.)) 00045 00046 #define IS_NAN_FLOAT(v) (((*(unsigned long *)&(v))&0x7f800000)==0x7f800000) 00047 #define IS_NAN_DOUBLE(v) (((((unsigned long *)&(v))[1])&0x7fe00000)==0x7fe00000) 00048 00049 #define IS_DENORM_NAN_FLOAT(v) (IS_DENORM_FLOAT(v)||IS_NAN_FLOAT(v)) 00050 #define IS_DENORM_NAN_DOUBLE(v) (IS_DENORM_DOUBLE(v)||IS_NAN_DOUBLE(v)) 00051 00052 // currently all little endian processors are x86 00053 #if defined(WIN_VERSION) || (defined(MAC_VERSION)&&TARGET_RT_LITTLE_ENDIAN) 00054 #define DENORM_WANT_FIX 1 00055 #endif 00056 00057 #ifdef DENORM_WANT_FIX 00058 00059 #define FIX_DENORM_FLOAT(v) ((v)=IS_DENORM_FLOAT(v)?0.f:(v)) 00060 #define FIX_DENORM_DOUBLE(v) ((v)=IS_DENORM_DOUBLE(v)?0.f:(v)) 00061 00062 #define FIX_DENORM_NAN_FLOAT(v) ((v)=IS_DENORM_NAN_FLOAT(v)?0.f:(v)) 00063 #define FIX_DENORM_NAN_DOUBLE(v) ((v)=IS_DENORM_NAN_DOUBLE(v)?0.:(v)) 00064 00065 #else 00066 00067 #define FIX_DENORM_FLOAT(v) 00068 #define FIX_DENORM_DOUBLE(v) 00069 00070 #define FIX_DENORM_NAN_FLOAT(v) 00071 #define FIX_DENORM_NAN_DOUBLE(v) 00072 00073 #endif 00074 00075 00076 // header for all DSP objects. Provides a proxy. 00077 00078 // z_misc flags: 00079 00080 #define Z_NO_INPLACE 1 ///< flag indicating the object doesn't want signals in place @ingroup msp 00081 #define Z_PUT_LAST 2 ///< when list of ugens is resorted, put this object at end @ingroup msp 00082 #define Z_PUT_FIRST 4 ///< when list of ugens is resorted, put this object at beginning @ingroup msp 00083 00084 typedef void *t_proxy; 00085 00086 /** Header for any non-ui signal processing object. 00087 For ui objects use #t_pxjbox. 00088 @ingroup msp */ 00089 typedef struct t_pxobject { 00090 struct object z_ob; ///< The standard #t_object struct. 00091 long z_in; 00092 #ifdef PROBE_TEST 00093 void *z_proxy; 00094 #else 00095 t_proxy *z_proxy; 00096 #endif 00097 long z_disabled; ///< set to non-zero if this object is muted (using the pcontrol or mute~ objects) 00098 short z_count; ///< an array that indicates what inlets/outlets are connected with signals 00099 short z_misc; ///< flags (bitmask) determining object behaviour, such as #Z_NO_INPLACE, #Z_PUT_FIRST, or #Z_PUT_LAST 00100 } t_pxobject; 00101 00102 00103 #define MAXLOGSIG 13 00104 #define MAXSIGSIZE (1 << MAXLOGSIG) 00105 /** The signal data structure. 00106 @ingroup msp */ 00107 typedef struct _signal 00108 { 00109 long s_n; ///< The vector size of the signal. 00110 t_sample *s_vec; ///< An array of buffers holding the vectors of audio. 00111 float s_sr; ///< The sample rate of the signal. 00112 struct _signal *s_next; 00113 struct _signal *s_nextused; 00114 short s_refcount; 00115 short s_size; // element size (* s_n == memory) 00116 char *s_ptr; // what to free 00117 } t_signal; 00118 00119 00120 // c74 private 00121 00122 typedef struct _dspchain 00123 { 00124 t_object c_ob; 00125 t_int *c_chain; 00126 long c_chainsize; 00127 long c_callcount; 00128 long c_usedcount; 00129 long c_reusedcount; 00130 long c_freedcount; 00131 long c_sr; 00132 long c_bs; 00133 t_signal *c_usedlist; 00134 t_signal *c_freelist; 00135 t_signal *c_zero; 00136 struct _ugenbox *c_ugenlist; // temporary variable, allows reentrant compiling 00137 struct _dspchain *c_prev; 00138 void *c_patcher; // top-level parent or 0 if global 00139 void *c_inlets; // collection of inlets 00140 void *c_outlets; // collection of outlets 00141 void *c_inputs; // signal input list (zero before first exec) 00142 void *c_outputs; // signal output list 00143 // have to determine whether freelist is global or local 00144 volatile long c_broken; // object being freed, don't run it 00145 long c_intype; // using old signal linklist (0) or array 00146 long c_outtype; // using old signal linklist (0) or array 00147 volatile long c_insidetick; // so we can set c_broken safely 00148 void *c_patchers; // used to keep track of all patchers in chain 00149 void *c_posttickobjects; // list of objects to be ticked after process 00150 } t_dspchain; 00151 00152 /** A function pointer for the audio perform routine used by MSP objects to process blocks of samples. @ingroup msp */ 00153 typedef t_int *(*t_perfroutine)(t_int *args); 00154 00155 00156 #ifndef VPTR_TYPEDEF 00157 /** A void pointer. @ingroup msp */ 00158 typedef void *t_vptr; 00159 /** A void pointer. @ingroup msp */ 00160 typedef void *vptr; 00161 #define VPTR_TYPEDEF 00162 #endif 00163 00164 // useful define 00165 00166 #ifndef PI 00167 /** The pi constant. @ingroup msp */ 00168 #define PI 3.14159265358979323846 00169 #endif 00170 #ifndef TWOPI 00171 /** Twice the pi constant. @ingroup msp */ 00172 #define TWOPI 6.28318530717958647692 00173 #endif // TWOPI 00174 #ifndef PIOVERTWO 00175 /** Half of the pi constant. @ingroup msp */ 00176 #define PIOVERTWO 1.57079632679489661923 00177 #endif // PIOVERTWO 00178 00179 // system access prototypes 00180 00181 BEGIN_USING_C_LINKAGE 00182 00183 // messages to the dsp object 00184 00185 void *dspmess(t_symbol *mess); 00186 00187 // access to DSP system variables 00188 00189 /** Query MSP for the maximum global vector (block) size. 00190 @ingroup msp 00191 @return The maximum global vector size for the MSP environment. */ 00192 int sys_getmaxblksize(void); 00193 00194 /** Query MSP for the current global vector (block) size. 00195 @ingroup msp 00196 @return The current global vector size for the MSP environment. */ 00197 int sys_getblksize(void); 00198 00199 /** Query MSP for the global sample rate. 00200 @ingroup msp 00201 @return The global sample rate of the MSP environment. */ 00202 float sys_getsr(void); 00203 00204 int sys_getch(void); // returns current number of channels 00205 int sys_optimize(void); // returns whether to optimize or not 00206 int sys_altivec(void); // returns whether machine has vector processing 00207 00208 /** Query MSP to determine whether or not it is running. 00209 @ingroup msp 00210 @return Returns true if the DSP is turned on, otherwise returns false. */ 00211 int sys_getdspstate(void); // returns whether audio is on or off 00212 00213 /** Query MSP to determine whether or not a given audio object is 00214 in a running dsp chain. This is preferable over sys_getdspstate() 00215 since global audio can be on but an object could be in a patcher that 00216 is not running. 00217 @ingroup msp 00218 @return Returns true if the MSP object is in a patcher that has audio on, otherwise returns false. 00219 */ 00220 int sys_getdspobjdspstate(t_object *o); 00221 00222 // controlling the DSP 00223 00224 void canvas_start_dsp(void); 00225 void canvas_stop_dsp(void); 00226 void dsp_tick(void); // no longer used 00227 00228 // the dspchain object 00229 00230 t_dspchain *dspchain_start(long bs, long sr); 00231 t_dspchain *dspchain_get(void); 00232 t_dspchain *dspchain_compile(t_patcher *p, long bs, long sr); 00233 t_dspchain *dspchain_compile2(t_patcher *p, t_dspchain *x); 00234 void dspchain_tick(t_dspchain *c); 00235 void canvas_start_onedsp(t_patcher *p, t_dspchain **c, long bs, long sr); 00236 void canvas_stop_onedsp(t_dspchain *c); 00237 void dspchain_setbroken(t_dspchain *c); 00238 00239 // utility perform routines 00240 00241 void set_zero(float *dst, long n); 00242 t_int *plus_perform(t_int *args); 00243 t_int *sig_perform(t_int *args); 00244 t_int *copy_perform(t_int *args); 00245 t_int *plus2_perform(t_int *w); 00246 00247 // setup routines used by DSP objects 00248 00249 /** Call this function in your MSP object's dsp method. 00250 This function adds your object's perform method to the DSP call chain 00251 and specifies the arguments it will be passed. 00252 argc, the number of 00253 arguments to your perform method, should be followed by argc 00254 additional arguments, all of which must be the size of a pointer or a long. 00255 00256 @ingroup msp 00257 @param f The perform routine to use for processing audio. 00258 @param n The number of arguments that will follow 00259 @param ... The arguments that will be passed to the perform routine. */ 00260 void dsp_add(t_perfroutine f, int n, ...); 00261 00262 /** Call this function in your MSP object's dsp method. 00263 Use dsp_addv() to add your object's perform routine to the DSP call 00264 chain and specify its arguments in an array rather than as arguments to 00265 a function. 00266 00267 @ingroup msp 00268 @param f The perform routine to use for processing audio. 00269 @param n The number of arguments that will follow in the vector parameter. 00270 @param vector The arguments that will be passed to the perform routine. */ 00271 void dsp_addv(t_perfroutine f, int n, void **vector); 00272 00273 00274 /** Call this routine after creating your object in the new instance routine 00275 with object_alloc(). Cast your object to #t_pxobject as the first 00276 argument, then specify the number of signal inputs your object will 00277 have. dsp_setup() initializes fields of the #t_pxobject header and 00278 allocates any proxies needed (if num_signal_inputs is greater than 1). 00279 00280 Some signal objects have no inputs; you should pass 0 for 00281 num_signal_inputs in this case. After calling dsp_setup(), you can 00282 create additional non-signal inlets using intin(), floatin(), or 00283 inlet_new(). 00284 00285 @ingroup msp 00286 @param x Your object's pointer. 00287 @param nsignals The number of signal/proxy inlets to create for the object. 00288 @see #dsp_setup */ 00289 void z_dsp_setup(t_pxobject *x, long nsignals); // called in new method 00290 00291 /** This is commonly used rather than directly calling z_dsp_setup() in MSP objects. 00292 @ingroup msp */ 00293 #define dsp_setup z_dsp_setup 00294 00295 00296 /** This function disposes of any memory used by proxies allocated by 00297 dsp_setup(). It also notifies the signal compiler that the DSP call chain 00298 needs to be rebuilt if signal processing is active. You should be sure to 00299 call this before de-allocating any memory that might be in use by your 00300 object’s perform routine, in the event that signal processing is on when 00301 your object is freed. 00302 00303 @ingroup msp 00304 @param x The object to free. 00305 @see #dsp_free */ 00306 void z_dsp_free(t_pxobject *x); 00307 00308 /** This is commonly used rather than directly calling z_dsp_free() in MSP objects. 00309 @ingroup msp */ 00310 #define dsp_free z_dsp_free 00311 00312 00313 void z_add_signalmethod(void); // called in initialization routine 00314 #define dsp_initclass z_add_signalmethod 00315 00316 void z_sysinit(void); 00317 #define dsp_sysinit z_sysinit 00318 00319 void z_patcher_for_dsp(t_object *x); 00320 #define dsp_patcher z_patcher_for_dsp 00321 00322 void dsp_setpatcher(void *p); 00323 00324 short z_isconnected(t_object *x, t_object *dst, short *index); 00325 #define dsp_isconnected z_isconnected 00326 00327 short z_dsp_setloadupdate(short way); 00328 #define dsp_setloadupdate z_dsp_setloadupdate 00329 00330 void *dsp_setpostprocess(method pm); 00331 void *dsp_setpreprocess(method pm); 00332 00333 // used only by audio driver objects 00334 00335 void sys_setprocessflag(short way); 00336 00337 // lame audio file utility (do not use) 00338 00339 short aiff_parse(char *header, long *offset, long *size, long *nchans, long *ssize, 00340 long *srate, void *chunk, void *markers); 00341 00342 // memory utilities 00343 00344 void *t_resizebytes(char *old, long oldsize, long newsize); 00345 void *t_getbytes(long size); 00346 void *t_freebytes(void *fatso, long size); 00347 00348 // atom utilities 00349 00350 t_int atom_getintarg(short which, short argc, t_atom *argv); 00351 float atom_getfloatarg(short which, short argc, t_atom *argv); 00352 t_symbol *atom_getsymarg(short which, short argc, t_atom *argv); 00353 00354 #define PROXY_GETINLET(x) proxy_getinlet(x) 00355 00356 00357 /** This routine must be called in your object's initialization routine. It 00358 adds a set of methods to your object's class that are called by MSP to 00359 build the DSP call chain. These methods function entirely 00360 transparently to your object so you don't have to worry about them. 00361 However, you should avoid binding anything to their names: signal, 00362 drawline, userconnect, and enable. 00363 00364 This routine is for normal (non-user-interface objects). 00365 It must be called prior to calling class_register() for your class. 00366 00367 @ingroup msp 00368 @param c The class to make dsp-ready. 00369 @see class_dspinitbox() */ 00370 void class_dspinit(t_class *c); 00371 00372 /** This routine must be called in your object's initialization routine. It 00373 adds a set of methods to your object's class that are called by MSP to 00374 build the DSP call chain. These methods function entirely 00375 transparently to your object so you don't have to worry about them. 00376 However, you should avoid binding anything to their names: signal, 00377 drawline, userconnect, and enable. 00378 00379 This routine is for normal user-interface objects. 00380 00381 @ingroup msp 00382 @param c The class to make dsp-ready. 00383 @see class_dspinit() */ 00384 void class_dspinitbox(t_class *c); 00385 00386 00387 // defines for SIMD optimization 00388 00389 // minimum vector size to use SIMD optimization 00390 #define DSP_OPTIMIZE_MIN 64 00391 00392 // simple (e.g. times, minus) not worth optimizing, disabled 00393 #define DSP_SIMPLE_OPTIMIZE_TEST(sigptr) (FALSE) 00394 00395 // simple parameter setting test (e.g. times, minus) not worth optimizing, disabled 00396 #define DSP_SIMPLE_OPTIMIZE_TEST_PARAM (FALSE) 00397 00398 // complex (e.g. cos, log, sqrt, fft family) optimize as long as enabled and vector is large enough 00399 #define DSP_COMPLEX_OPTIMIZE_TEST(sigptr) (FALSE) 00400 //#define DSP_COMPLEX_OPTIMIZE_TEST(sigptr) (sys_optimize()&&(sigptr)&&(sigptr)->s_n>=DSP_OPTIMIZE_MIN) 00401 00402 // buffered routines optimize always if enabled since signal vector isn't relevant 00403 #define DSP_BUFFERED_OPTIMIZE_TEST(sigptr) (FALSE) 00404 //#define DSP_BUFFERED_OPTIMIZE_TEST(sigptr) (sys_optimize()) 00405 00406 00407 00408 END_USING_C_LINKAGE 00409 00410 #if C74_PRAGMA_STRUCT_PACKPUSH 00411 #pragma pack(pop) 00412 #elif C74_PRAGMA_STRUCT_PACK 00413 #pragma pack() 00414 #endif 00415 00416 //-- ddz, so this is OK, just needs jpatcher_api.h first, right? 00417 00418 #if defined(_JPATCHER_API_H_) || defined(_DOXY_) 00419 BEGIN_USING_C_LINKAGE 00420 00421 00422 /** Header for any ui signal processing object. 00423 For non-ui objects use #t_pxobject. 00424 @ingroup msp */ 00425 typedef struct _pxjbox { 00426 t_jbox z_box; ///< The box struct used by all ui objects. 00427 long z_in; 00428 #ifdef PROBE_TEST 00429 void *z_proxy; 00430 #else 00431 t_proxy *z_proxy; 00432 #endif 00433 long z_disabled; ///< set to non-zero if this object is muted (using the pcontrol or mute~ objects) 00434 short z_count; ///< an array that indicates what inlets/outlets are connected with signals 00435 short z_misc; ///< flags (bitmask) determining object behaviour, such as #Z_NO_INPLACE, #Z_PUT_FIRST, or #Z_PUT_LAST 00436 } t_pxjbox; 00437 00438 00439 /** Configure a class to be ready for use with the MSP signal chain. 00440 You must call this function when your class is initialized (typically in the main() function) 00441 for an object to process audio. 00442 @ingroup msp 00443 @param c The pointer to the class being configured. */ 00444 void class_dspinitjbox(t_class *c); 00445 00446 void z_jbox_dsp_setup(t_pxjbox *x, long nsignals); 00447 void z_jbox_dsp_free(t_pxjbox *x); 00448 00449 #define dsp_setupjbox z_jbox_dsp_setup 00450 #define dsp_freejbox z_jbox_dsp_free 00451 00452 END_USING_C_LINKAGE 00453 00454 00455 #endif // _JPATCHER_API_H_ 00456 #endif // _Z_DSP_H 00457
Copyright © 2008, Cycling '74