Max 5 API Reference
00001 /** 00002 @file 00003 simplemsp - an MSP object shell 00004 jeremy bernstein - jeremy@bootsquad.com 00005 00006 @ingroup examples 00007 */ 00008 00009 #include "ext.h" // standard Max include, always required (except in Jitter) 00010 #include "ext_obex.h" // required for new style objects 00011 #include "z_dsp.h" // required for MSP objects 00012 00013 ////////////////////////// object struct 00014 typedef struct _simplemsp 00015 { 00016 t_pxobject ob; // the object itself (t_pxobject in MSP) 00017 float offset; 00018 } t_simplemsp; 00019 00020 ///////////////////////// function prototypes 00021 //// standard set 00022 void *simplemsp_new(t_symbol *s, long argc, t_atom *argv); 00023 void simplemsp_free(t_simplemsp *x); 00024 void simplemsp_assist(t_simplemsp *x, void *b, long m, long a, char *s); 00025 00026 void simplemsp_float(t_simplemsp *x, double f); 00027 00028 void simplemsp_dsp(t_simplemsp *x, t_signal **sp, short *count); 00029 t_int *simplemsp_perform(t_int *w); 00030 //////////////////////// global class pointer variable 00031 void *simplemsp_class; 00032 00033 00034 int main(void) 00035 { 00036 // object initialization, note the use of dsp_free for the freemethod, which is required 00037 // unless you need to free allocated memory, in which case you should call dsp_free from 00038 // your custom free function. 00039 00040 // OLD METHOD 00041 // setup((t_messlist **)&simplemsp_class, (method)simplemsp_new, (method)dsp_free, (short)sizeof(t_simplemsp), 0L, A_GIMME, 0); 00042 // addfloat((method)simplemsp_float); 00043 // you need this 00044 // addmess((method)simplemsp_dsp, "dsp", A_CANT, 0); 00045 // addmess((method)simplemsp_assist, "assist", A_CANT, 0); 00046 // you need this 00047 // dsp_initclass(); 00048 00049 // NEW METHOD 00050 t_class *c; 00051 00052 c = class_new("simplemsp~", (method)simplemsp_new, (method)dsp_free, (long)sizeof(t_simplemsp), 0L, A_GIMME, 0); 00053 00054 class_addmethod(c, (method)simplemsp_float, "float", A_FLOAT, 0); 00055 class_addmethod(c, (method)simplemsp_dsp, "dsp", A_CANT, 0); 00056 class_addmethod(c, (method)simplemsp_assist, "assist", A_CANT, 0); 00057 00058 class_dspinit(c); // new style object version of dsp_initclass(); 00059 class_register(CLASS_BOX, c); // register class as a box class 00060 simplemsp_class = c; 00061 00062 return 0; 00063 } 00064 00065 void simplemsp_float(t_simplemsp *x, double f) 00066 { 00067 x->offset = f; 00068 } 00069 00070 // this function is called when the DAC is enabled, and "registers" a function 00071 // for the signal chain. in this case, "simplemsp_perform" 00072 void simplemsp_dsp(t_simplemsp *x, t_signal **sp, short *count) 00073 { 00074 post("my sample rate is: %f", sp[0]->s_sr); 00075 00076 // dsp_add 00077 // 1: (t_perfroutine p) perform method 00078 // 2: (long argc) number of args to your perform method 00079 // 3...: argc additional arguments, all must be sizeof(pointer) or long 00080 // these can be whatever, so you might want to include your object pointer in there 00081 // so that you have access to the info, if you need it. 00082 dsp_add(simplemsp_perform, 4, x, sp[0]->s_vec, sp[1]->s_vec, sp[0]->s_n); 00083 } 00084 00085 t_int *simplemsp_perform(t_int *w) 00086 { 00087 // DO NOT CALL post IN HERE, but you can call defer_low (not defer) 00088 00089 // args are in a vector, sized as specified in simplemsp_dsp method 00090 // w[0] contains &simplemsp_perform, so we start at w[1] 00091 t_simplemsp *x = (t_simplemsp *)(w[1]); 00092 t_float *inL = (t_float *)(w[2]); 00093 t_float *outL = (t_float *)(w[3]); 00094 int n = (int)w[4]; 00095 00096 // this perform method simply copies the input to the output, offsetting the value 00097 while (n--) 00098 *outL++ = *inL++ + x->offset; 00099 00100 // you have to return the NEXT pointer in the array OR MAX WILL CRASH 00101 return w + 5; 00102 } 00103 00104 void simplemsp_assist(t_simplemsp *x, void *b, long m, long a, char *s) 00105 { 00106 if (m == ASSIST_INLET) { //inlet 00107 sprintf(s, "I am inlet %ld", a); 00108 } 00109 else { // outlet 00110 sprintf(s, "I am outlet %ld", a); 00111 } 00112 } 00113 00114 // NOT CALLED!, we use dsp_free for a generic free function 00115 void simplemsp_free(t_simplemsp *x) 00116 { 00117 ; 00118 } 00119 00120 void *simplemsp_new(t_symbol *s, long argc, t_atom *argv) 00121 { 00122 t_simplemsp *x = NULL; 00123 00124 // OLD VERSION 00125 // if (x = (t_simplemsp *)newobject(simplemsp_class)) { 00126 00127 // NEW VERSION 00128 if (x = (t_simplemsp *)object_alloc(simplemsp_class)) { 00129 dsp_setup((t_pxobject *)x, 1); // MSP inlets: arg is # of inlets and is REQUIRED! 00130 // use 0 if you don't need inlets 00131 outlet_new(x, "signal"); // signal outlet (note "signal" rather than NULL) 00132 x->offset = 0.; 00133 } 00134 return (x); 00135 }
Copyright © 2008, Cycling '74