Max 5 API Reference
00001 /** 00002 00003 @defgroup msp MSP 00004 00005 00006 @defgroup buffers Buffers 00007 @ingroup msp 00008 00009 Your object can access shared data stored in an MSP buffer~ object. 00010 Similar to table and coll objects, buffer~ objects are bound to a #t_symbol from which you can gain access to the #t_buffer struct. 00011 Consider the following example. 00012 00013 @code 00014 t_symbol *s; 00015 t_object *o; 00016 00017 s = gensym("foo"); 00018 o = s->s_thing; 00019 00020 // if an object is bound to the symbol "foo", then o is that object. 00021 if (ob_sym(o) == gensym("buffer~")) { 00022 // that object is a buffer~, so we can use it 00023 x->x_buffer = (t_buffer*)o; 00024 00025 } 00026 @endcode 00027 00028 Having stored a pointer to the buffer~ is the first step toward working with its data. 00029 However, you must not go accessing the data directly without taking some precautions regarding thread-safety. 00030 00031 To access the data in a buffer you first increment the b_inuse member of the #t_buffer's struct. 00032 Then you perform the requisite operations on the data, which is stored in the b_samples member. 00033 When you are done you decrement the b_inuse member to return it to the state in which you found it. 00034 00035 In the past you may have set the buffer's b_inuse flag directly and cleared it when you were done. 00036 This is no longer good enough, and you must instead use the threadsafe macros #ATOMIC_INCREMENT and #ATOMIC_DECREMENT 00037 for modifying the b_inuse flag. 00038 The example below demonstrates what this might look like in an MSP object's perform routine. 00039 Notice that extra care has been taken to ensure that the #ATOMIC_INCREMENT is always balanced with an #ATOMIC_DECREMENT call. 00040 00041 @code 00042 ATOMIC_INCREMENT(&x->w_buf->b_inuse); 00043 if (!x->w_buf->b_valid) { 00044 ATOMIC_DECREMENT(&x->w_buf->b_inuse); 00045 goto byebye; 00046 } 00047 00048 // do something with the buffer 00049 00050 ATOMIC_DECREMENT(&x->w_buf->b_inuse); 00051 byebye: 00052 return (w + 7); 00053 @endcode 00054 00055 A class that accesses buffer~ objects is the simpwave~ object that is included with Max 5 SDK example projects. 00056 00057 00058 00059 00060 00061 00062 @defgroup pfft PFFT 00063 @ingroup msp 00064 00065 When an object is instantiated, it is possible to determine if it is being created in pfft~ context in the new method. 00066 In the new method (and only at this time), you can check the s_thing member of the #t_symbol '__pfft~__'. 00067 If this is non-null, then you will have a pointer to a #t_pfftpub struct. 00068 00069 @code 00070 t_pfftpub *pfft_parent = (t_pfftpub*) gensym("__pfft~__")->s_thing; 00071 00072 if (pfft_parent) { 00073 // in a pfft~ context 00074 } 00075 else { 00076 // not in a pfft~ 00077 } 00078 @endcode 00079 00080 00081 00082 @defgroup poly Poly 00083 @ingroup msp 00084 00085 If your object is instatiated as a voice of a poly~ object, it is possible both to determine this context 00086 and to determine information about the specific voice. 00087 This is done by querying the patcher in which your object exists for an associated object, and then calling methods on that object. 00088 00089 @code 00090 t_object *patcher = NULL; 00091 t_max_err err = MAX_ERR_NONE; 00092 t_object *assoc = NULL; 00093 method m = NULL; 00094 long voices = -1; 00095 long index = -1; 00096 00097 err = object_obex_lookup(x, gensym("#P"), &patcher); 00098 if (err == MAX_ERR_NONE) { 00099 object_method(patcher, gensym("getassoc"), &assoc); 00100 if (assoc) { 00101 post("found %s", object_classname(assoc)->s_name); 00102 00103 voices = object_attr_getlong(assoc, gensym("voices")); 00104 post("total amount of voices: %ld", voices); 00105 00106 if(m = zgetfn(assoc, gensym("getindex"))) 00107 index = (long)(*m)(assoc, patcher); 00108 post("index: %ld", index); 00109 } 00110 } 00111 00112 @endcode 00113 00114 00115 00116 */
Copyright © 2008, Cycling '74