github.com/256dpi/max-go@v0.7.0/lib/msp/z_dsp.h (about)

     1  // z_dsp.h -- the main header file for all DSP objects copyright 1997-2003 Cycling '74
     2  
     3  // DSP services:
     4  
     5  #ifndef _Z_DSP_H
     6  #define _Z_DSP_H
     7  	
     8  #include "z_sampletype.h"
     9  #include "ext_systhread.h"
    10  #include "ext_linklist.h"
    11  #include "ext_atomic.h"
    12  #include "ext_maxtypes.h"
    13  
    14  #if C74_PRAGMA_STRUCT_PACKPUSH
    15      #pragma pack(push, 2)
    16  #elif C74_PRAGMA_STRUCT_PACK
    17      #pragma pack(2)
    18  #endif
    19  
    20  /**	MSP System Properties.
    21  	@ingroup	 msp	*/
    22  enum {
    23  	SYS_MAXBLKSIZE = 2048	///< a good number for a maximum signal vector size
    24  };
    25  
    26  // maximum channels in a multi-channel signal
    27  
    28  #define MC_MAX_CHANS 1024
    29  
    30  // suggested maximum number of inlets or outlets in a multi-channel object
    31  // this is not a hard limit, just a way to keep people from making objects
    32  // with huge numbers of inlets and outlets by mistake
    33  
    34  #define MC_MAX_IO 64
    35  
    36  // header for all DSP objects. Provides a proxy.
    37  
    38  // z_misc flags:
    39  
    40  #define Z_NO_INPLACE 1	///< flag indicating the object doesn't want signals in place @ingroup msp
    41  #define Z_PUT_LAST 2	///< when list of ugens is resorted, put this object at end @ingroup msp
    42  #define Z_PUT_FIRST 4	///< when list of ugens is resorted, put this object at beginning @ingroup msp
    43  #define Z_IGNORE_DISABLE 8	///< ignore the disable field when executing the chain, e.g. to process the pass~ object in a muted patcher.
    44  #define Z_DONT_ADD 16		///< if this flag is set the object will be ignored and its dsp method won't be called.
    45  #define Z_MC_INLETS 32	///< object knows how to count channels of incoming multi-channel signals
    46  
    47  #define SIXTEENIZE(p) ((((t_ptr_uint)(p)) + 16) & (~(t_ptr_uint)0xF))
    48  #define THIRTYTWOIZE(p) ((((t_ptr_uint)(p)) + 32) & (~(t_ptr_uint)0x1F))
    49  
    50  typedef void *t_proxy;
    51  
    52  /**	Common struct for MSP objects. 
    53   @ingroup	msp	*/
    54  typedef struct _pxdata {
    55  	long	z_in;
    56  	void	*z_proxy;
    57  	long	z_disabled;		///< set to non-zero if this object is muted (using the pcontrol or mute~ objects)
    58  	short	z_count;		///< the number of signal inlets
    59  	short	z_misc;			///< flags (bitmask) determining object behaviour, such as #Z_NO_INPLACE, #Z_PUT_FIRST, or #Z_PUT_LAST
    60  } t_pxdata; 
    61  
    62  /**	Header for any non-ui signal processing object. 
    63  	For ui objects use #t_pxjbox.
    64  	@ingroup	msp	*/
    65  typedef struct t_pxobject {
    66  	struct object z_ob;	///< The standard #t_object struct.
    67  	long z_in;
    68  	void *z_proxy;
    69  	long z_disabled;	///< set to non-zero if this object is muted (using the pcontrol or mute~ objects)
    70  	short z_count;		///< the number of signal inlets
    71  	short z_misc;		///< flags (bitmask) determining object behaviour, such as #Z_NO_INPLACE, #Z_PUT_FIRST, or #Z_PUT_LAST
    72  } t_pxobject;
    73  
    74  
    75  #define MAXLOGSIG 13
    76  #define MAXSIGSIZE (1 << MAXLOGSIG)
    77  /** The signal data structure.
    78  	@ingroup	msp	*/
    79  typedef struct _signal
    80  {
    81      long s_n;						///< The vector size of the signal.
    82      t_sample *s_vec;				///< A buffer holding the vector of audio samples.
    83      float s_sr;						///< The sample rate of the signal.
    84      struct _signal *s_next;
    85      struct _signal *s_nextused;
    86      short s_refcount;
    87      short s_size;					// element size (* s_n == memory)
    88      char *s_ptr;					// what to free
    89  } t_signal;
    90  
    91  
    92  // c74 private
    93  
    94  struct _chain64item;
    95  struct _chain64item_extra;
    96  
    97  typedef struct _dspchain
    98  {
    99  	t_object c_ob;
   100  	t_int *c_chain;
   101  	long c_chainsize;
   102  	long c_callcount;
   103  	long c_usedcount;
   104  	long c_reusedcount;
   105  	long c_freedcount;
   106  	long c_sr;
   107  	long c_bs;
   108  	t_signal *c_usedlist;
   109  	t_signal *c_freelist;
   110  	t_signal *c_zero;
   111  	struct _ugenbox *c_ugenlist;	// temporary variable, allows reentrant compiling
   112  	struct _dspchain *c_prev;
   113  	void *c_patcher;				// top-level parent or 0 if global
   114  	void *c_inlets;					// collection of inlets
   115  	void *c_outlets;				// collection of outlets
   116  	void *c_inputs;					// signal input list (zero before first exec)
   117  	void *c_outputs; 				// signal output list
   118  	// have to determine whether freelist is global or local
   119  	volatile long c_broken;			// object being freed, don't run it
   120  	long c_intype;					// using old signal linklist (0) or array
   121  	long c_outtype;					// using old signal linklist (0) or array
   122  	t_int32_atomic c_dontbreak;		// temporarily prevent chain from being broken
   123  	t_int32_atomic c_wantsbreak;		// so main thread can tell audio thread it wants to become broken
   124  	void *c_patchers;				// used to keep track of all patchers in chain
   125  	void *c_posttickobjects;		// list of objects to be ticked after process (called from same thread as dspchain is ticked from)
   126  	void *c_mixerlisteners;			// list of objects listening to various mixer notifications
   127  	void *unused;					// was c_chain64 but no longer used
   128  	struct _ugenbox *c_curugen;		// internal use: ugenbox pointer to current box during dsp64 method call 
   129  	t_object *c_implicitugens;		// internal use
   130  	long c_32bitchain;				// flag set when this is really a 32 bit chain (for wrapper)
   131  	long c_benchmark;				// flag set when benchmarking cpu consumption
   132  	double c_benchtime_used;		// cumulative cputime (in milliseconds) used for ticking all objects in the chain (only when benchmarking is enabled)
   133  	double c_benchtime_available;	// cumulative time (in milliseconds) since this dspchain has been started (only when benchmarking is enabled)
   134  	long c_chain64_alloclen; 
   135  	long c_chain64_len; 
   136  	struct _chain64item *c_chain64_array; 
   137  	struct _chain64item_extra *c_chain64_extra_array;
   138  } t_dspchain;
   139  
   140  #ifndef VPTR_TYPEDEF
   141  /** A void pointer.		@ingroup msp	*/
   142  typedef void *t_vptr;
   143  /** A void pointer.		@ingroup msp	*/
   144  typedef void *vptr;
   145  #define VPTR_TYPEDEF
   146  #endif 
   147  
   148  // useful define
   149  
   150  #ifndef PI
   151  /** The pi constant.				@ingroup msp	*/
   152  #define PI 3.14159265358979323846
   153  #endif
   154  #ifndef TWOPI
   155  /** Twice the pi constant.			@ingroup msp	*/
   156  #define TWOPI		6.28318530717958647692
   157  #endif  // TWOPI
   158  #ifndef PIOVERTWO
   159  /** Half of the pi constant.		@ingroup msp	*/
   160  #define PIOVERTWO	1.57079632679489661923
   161  #endif  // PIOVERTWO
   162  
   163  // system access prototypes
   164  
   165  BEGIN_USING_C_LINKAGE 
   166  
   167  /**	A function pointer for the audio perform routine used by MSP objects to process blocks of samples. @ingroup msp */
   168  typedef t_int *(*t_perfroutine)(t_int *args);
   169  
   170  typedef void (*t_perfroutine64)(t_object *x, t_object *dsp64, double **ins, long numins, double **outs, long numouts, long sampleframes, long flags, void *userparam); 
   171  
   172  // messages to the dsp object
   173  
   174  void *dspmess(t_symbol *mess);
   175  
   176  // access to DSP system variables
   177  
   178  /**	Query MSP for the maximum global vector (block) size.
   179  	@ingroup	msp	
   180  	@return		The maximum global vector size for the MSP environment.		*/
   181  int sys_getmaxblksize(void);
   182  
   183  /**	Query MSP for the current global vector (block) size.
   184  	@ingroup	msp	
   185  	@return		The current global vector size for the MSP environment.		*/
   186  int sys_getblksize(void);
   187  
   188  /**	Query MSP for the global sample rate.
   189  	@ingroup	msp	
   190  	@return		The global sample rate of the MSP environment.		*/
   191  float sys_getsr(void);
   192  
   193  int sys_getch(void);			// returns current number of channels
   194  int sys_optimize(void);			// returns whether to optimize or not
   195  int sys_altivec(void);			// returns whether machine has vector processing
   196  
   197  /**	Query MSP to determine whether or not it is running.
   198  	@ingroup	msp	
   199  	@return		Returns true if the DSP is turned on, otherwise returns false.		*/
   200  int sys_getdspstate(void);		// returns whether audio is on or off
   201  
   202  /** Query MSP to determine whether or not a given audio object is 
   203      in a running dsp chain.  This is preferable over sys_getdspstate() 
   204  	since global audio can be on but an object could be in a patcher that
   205  	is not running. 
   206  	@ingroup	msp
   207  	@return		Returns true if the MSP object is in a patcher that has audio on, otherwise returns false. 
   208  */
   209  int sys_getdspobjdspstate(t_object *o);  
   210  
   211  // controlling the DSP
   212  
   213  void canvas_start_dsp(void);
   214  void canvas_stop_dsp(void);
   215  void dsp_tick(void);			// no longer used
   216  
   217  // the dspchain object
   218  
   219  #define DSPCHAIN_MIXERLISTENER_WILLPROCESSIOVECTOR		(0x00000001)
   220  #define DSPCHAIN_MIXERLISTENER_WILLPROCESSMIXER			(0x00000002)
   221  #define DSPCHAIN_MIXERLISTENER_DIDPROCESSMIXER			(0x00000004)
   222  #define DSPCHAIN_MIXERLISTENER_DIDPROCESSIOVECTOR		(0x00000008)
   223  #define DSPCHAIN_MIXERLISTENER_MIXERGRAPHWILLSTART		(0x00000010)
   224  #define DSPCHAIN_MIXERLISTENER_MIXERGRAPHWILLSTOP		(0x00000020)
   225  
   226  t_dspchain *dspchain_start(long bs, long sr);
   227  t_dspchain *dspchain_get(void);
   228  t_dspchain *dspchain_compile(t_patcher *p, long bs, long sr);
   229  t_dspchain *dspchain_compile2(t_patcher *p, t_dspchain *x);
   230  void dspchain_tick(t_dspchain *c);
   231  void canvas_start_onedsp(t_patcher *p, t_dspchain **c, long bs, long sr); 
   232  void canvas_stop_onedsp(t_dspchain *c);
   233  void dspchain_setbroken(t_dspchain *c);
   234  t_max_err dspchain_lock(t_dspchain *c); 
   235  void dspchain_unlock(t_dspchain *c); 
   236  t_dspchain *dspchain_fromobject(t_object *o); 
   237  void dspchain_addmixerlistener(t_dspchain *chain, t_object *listener, long notifications); 
   238  
   239  // utility perform routines
   240  
   241  void set_zero(float *dst, long n);
   242  void set_zero64(double *dst, long n);
   243  void copy_64from32(t_double *dst, const t_float *src, long n);
   244  void copy_32from64(t_float *dst, const t_double *src, long n);
   245  t_int *plus_perform(t_int *args);
   246  t_int *plus_perform64(t_int *args);
   247  t_int *sig_perform(t_int *args);
   248  t_int *sig_perform64(t_int *args);
   249  t_int *copy_perform(t_int *args);
   250  t_int *copy_perform64(t_int *args);
   251  t_int *plus2_perform(t_int *w);
   252  t_int *plus2_perform64(t_int *w);
   253  
   254  // setup routines used by DSP objects
   255  
   256  /**	Call this function in your MSP object's dsp method.
   257  	This function adds your object's perform method to the DSP call chain 
   258  	and specifies the arguments it will be passed. 
   259  	n, the number of arguments to your perform method, should be followed by n 
   260  	additional arguments, all of which must be the size of a pointer or a long.
   261  	
   262  	@ingroup	msp
   263  	@param	f	The perform routine to use for processing audio.
   264  	@param	n	The number of arguments that will follow
   265  	@param	...	The arguments that will be passed to the perform routine.	
   266  	@see		@ref chapter_msp_anatomy_dsp
   267  	@see		@ref chapter_msp_advanced_connections	*/
   268  C74_DEPRECATED( void dsp_add(t_perfroutine f, int n, ...) );
   269  
   270  /**	Call this function in your MSP object's dsp method.
   271  	Use dsp_addv() to add your object's perform routine to the DSP call 
   272  	chain and specify its arguments in an array rather than as arguments to 
   273  	a function. 
   274  		
   275  	@ingroup		msp
   276  	@param	f		The perform routine to use for processing audio.
   277  	@param	n		The number of arguments that will follow in the vector parameter.
   278  	@param	vector 	The arguments that will be passed to the perform routine.
   279  	@see			@ref chapter_msp_anatomy_dsp
   280  	@see			@ref chapter_msp_advanced_connections	*/
   281  C74_DEPRECATED( void dsp_addv(t_perfroutine f, int n, void **vector) );
   282  
   283  // objects should only have one perform method
   284  // in exceptional cases there may be a situation where warnings about this need to be disabled.
   285  // this flag to dsp_add64 will accomplish that
   286  // for internal use only
   287  #define DSP_ADD64_FLAG_INTERNALITEM (0x00000001)
   288  
   289  void dsp_add64(t_object *chain, t_object *x, t_perfroutine64 f, long flags, void *userparam); 
   290  
   291  /**	Call this routine after creating your object in the new instance routine 
   292  	with object_alloc(). Cast your object to #t_pxobject as the first 
   293  	argument, then specify the number of signal inputs your object will 
   294  	have. dsp_setup() initializes fields of the #t_pxobject header and 
   295  	allocates any proxies needed (if num_signal_inputs is greater than 1).
   296  	
   297  	Some signal objects have no inputs; you should pass 0 for 
   298  	num_signal_inputs in this case. After calling dsp_setup(), you can 
   299  	create additional non-signal inlets using intin(), floatin(), or 
   300  	inlet_new().
   301  
   302  	@ingroup			msp
   303  	@param	x			Your object's pointer.
   304  	@param	nsignals	The number of signal/proxy inlets to create for the object.
   305  	@see 				#dsp_setup	*/
   306  void z_dsp_setup(t_pxobject *x, long nsignals);		// called in new method
   307  
   308  /**	This is commonly used rather than directly calling z_dsp_setup() in MSP objects.
   309   	@ingroup	msp	*/
   310  #define dsp_setup z_dsp_setup
   311  
   312  void dsp_resize(t_pxobject *x, long nsignals); // for dynamic inlets
   313  
   314  
   315  /**	This function disposes of any memory used by proxies allocated by 
   316  	dsp_setup(). It also notifies the signal compiler that the DSP call chain 
   317  	needs to be rebuilt if signal processing is active. You should be sure to 
   318  	call this before de-allocating any memory that might be in use by your 
   319  	object’s perform routine, in the event that signal processing is on when 
   320  	your object is freed.
   321  
   322  	@ingroup	msp
   323  	@param	x	The object to free.
   324  	@see		#dsp_free	*/
   325  void z_dsp_free(t_pxobject *x);
   326  
   327  /**	This is commonly used rather than directly calling z_dsp_free() in MSP objects.
   328   	@ingroup	msp	*/
   329  #define dsp_free z_dsp_free
   330  
   331  
   332  C74_DEPRECATED ( void z_add_signalmethod(void) );						// called in initialization routine
   333  #define dsp_initclass z_add_signalmethod
   334  
   335  void z_sysinit(void);
   336  #define dsp_sysinit z_sysinit
   337  
   338  void dsp_setpatcher(void *p);
   339  void *dsp_getpatcher();
   340  
   341  short z_isconnected(t_object *x, t_object *dst, short *index);
   342  #define dsp_isconnected z_isconnected
   343  
   344  short z_dsp_setloadupdate(short way);
   345  #define dsp_setloadupdate z_dsp_setloadupdate
   346  
   347  void *dsp_setpostprocess(method pm);
   348  void *dsp_setpreprocess(method pm);
   349  
   350  // used only by audio driver objects
   351  
   352  void sys_setprocessflag(short way);
   353  
   354  // lame audio file utility (do not use)
   355  
   356  short aiff_parse(char *header, long *offset, long *size, long *nchans, long *ssize,
   357  	long *srate, void *chunk, void *markers);
   358  
   359  // memory utilities
   360  
   361  void *t_resizebytes(char *old, long oldsize, long newsize);
   362  void *t_getbytes(long size);
   363  void *t_freebytes(void *fatso, long size);
   364  
   365  // atom utilities
   366  
   367  t_int atom_getintarg(short which, short argc, t_atom *argv);
   368  float atom_getfloatarg(short which, short argc, t_atom *argv);
   369  t_symbol *atom_getsymarg(short which, short argc, t_atom *argv);
   370  
   371  #define PROXY_GETINLET(x) proxy_getinlet(x)
   372  
   373  
   374  /**	This routine must be called in your object's initialization routine. It 
   375  	adds a set of methods to your object's class that are called by MSP to 
   376  	build the DSP call chain. These methods function entirely 
   377  	transparently to your object so you don't have to worry about them. 
   378  	However, you should avoid binding anything to their names: signal, 
   379  	userconnect, nsiginlets, and enable. 
   380  	
   381  	This routine is for non-user-interface objects only
   382  	(where the first item in your object's struct is a t_pxobject).
   383  	It must be called prior to calling class_register() for your class.
   384  
   385  	@ingroup	msp
   386  	@param	c	The class to make dsp-ready.
   387  	@see		class_dspinitjbox()	*/
   388  void class_dspinit(t_class *c);
   389  
   390  /**	This routine must be called in your object's initialization routine. It 
   391  	adds a set of methods to your object's class that are called by MSP to 
   392  	build the DSP call chain. These methods function entirely 
   393  	transparently to your object so you don't have to worry about them. 
   394  	However, you should avoid binding anything to their names: signal, 
   395  	userconnect, nsiginlets, and enable. 
   396  	
   397  	This routine is for user-interface objects only
   398  	(where the first item in your object's struct is a t_jbox). 
   399  
   400  	@ingroup	msp
   401  	@param	c	The class to make dsp-ready.
   402  	@see		class_dspinit()	*/
   403  void class_dspinitjbox(t_class *c);
   404  
   405  
   406  // defines for SIMD optimization
   407  
   408  // minimum vector size to use SIMD optimization
   409  #define DSP_OPTIMIZE_MIN	64
   410  
   411  // simple (e.g. times, minus) not worth optimizing, disabled
   412  #define DSP_SIMPLE_OPTIMIZE_TEST(sigptr)		(FALSE)
   413  
   414  // simple parameter setting test (e.g. times, minus) not worth optimizing, disabled
   415  #define DSP_SIMPLE_OPTIMIZE_TEST_PARAM			(FALSE)
   416  
   417  // complex (e.g. cos, log, sqrt, fft family) optimize as long as enabled and vector is large enough
   418  #define DSP_COMPLEX_OPTIMIZE_TEST(sigptr)		(FALSE)
   419  //#define DSP_COMPLEX_OPTIMIZE_TEST(sigptr)		(sys_optimize()&&(sigptr)&&(sigptr)->s_n>=DSP_OPTIMIZE_MIN)
   420  
   421  // buffered routines optimize always if enabled since signal vector isn't relevant
   422  #define DSP_BUFFERED_OPTIMIZE_TEST(sigptr)		(FALSE)
   423  //#define DSP_BUFFERED_OPTIMIZE_TEST(sigptr)	(sys_optimize())
   424  
   425  
   426  
   427  END_USING_C_LINKAGE 
   428  
   429  #if C74_PRAGMA_STRUCT_PACKPUSH
   430      #pragma pack(pop)
   431  #elif C74_PRAGMA_STRUCT_PACK
   432      #pragma pack()
   433  #endif
   434  
   435  //-- ddz, so this is OK, just needs jpatcher_api.h first, right?
   436  
   437  #if defined(_JPATCHER_API_H_) || defined(_DOXY_)
   438  BEGIN_USING_C_LINKAGE
   439  
   440  
   441  /**	Header for any ui signal processing object. 
   442  	For non-ui objects use #t_pxobject.
   443  	@ingroup	msp	*/
   444  typedef struct _pxjbox {
   445  	t_jbox	z_box;			///< The box struct used by all ui objects.
   446  	long	z_in;
   447  	void	*z_proxy;
   448  	long	z_disabled;		///< set to non-zero if this object is muted (using the pcontrol or mute~ objects)
   449  	short	z_count;		///< the number of signal inlets
   450  	short	z_misc;			///< flags (bitmask) determining object behaviour, such as #Z_NO_INPLACE, #Z_PUT_FIRST, or #Z_PUT_LAST
   451  } t_pxjbox;
   452  
   453  void z_jbox_dsp_setup(t_pxjbox *x, long nsignals); 
   454  void z_jbox_dsp_free(t_pxjbox *x);
   455  
   456  #define dsp_setupjbox z_jbox_dsp_setup
   457  #define dsp_freejbox z_jbox_dsp_free
   458  
   459  END_USING_C_LINKAGE
   460  
   461  
   462  #endif // _JPATCHER_API_H_
   463  #endif // _Z_DSP_H
   464