On Sep 21, 2009, at 5:10 PM, mescali...@gmail.com wrote:

Jakob Leben wrote:
On Sun, Sep 13, 2009 at 9:01 PM, mescali...@gmail.com
<mailto:mescali...@gmail.com> <mescali...@gmail.com
<mailto:mescali...@gmail.com>> wrote:

if I were writing an external that is somewhat an interface to arrays
   (read/write), I have some design choices:

1) copy/paste the code of array (g_array.c) (or eventually only copy
   [tabread]/[tabwrite])
      pros: resulting external is tight & tidy
      cons: code duplication, possible breakage in future releases

   2) provide appropriate inlets and outlets, and require the user to
   patch
   the external among [tabread]/[tabwrite] objects
      pros: modular. is independent from the array implementation.
      cons: tricky to use, the user can patch it incorrectly and
   won't work.

   3) is possible to patch the required objects without phisically
   put them
   in the canvas [?]
      pros: all pros mentioned in 1) and 2)
      cons: [?]

   obviously, 1) and 2) are ugly under some point of view; what I am
interested in is 3), hence asking here if possible, and directions on
   how to proceed.


I would suggest the following two options. Everything used in the
examples is declared in the "m_pd.h" header that you have to include
in your external anyway. Basically, I will explain the techniques used
by the pd objects that operate on arrays and the delay objects, so
this is stuff that will most probably not be broken for numerous
future releases, or a very large part of pd should drastically change.

1.
You can get a direct pointer to data stored in a g_array with the
following code:

t_symbol *array_name = gensym( "array-named-foo");
t_pd *the_array = *pd_findbyclass*(  array_name, garray_class );
int size;
t_float *data;
*garray_getfloatarray*( (t_garray) the_array, &size, &data );

You have to pass the name of the array as it was set in the pd patch
as the "s" argument of pd_findbyclass function. Therefore you can
easily let the user choose the array you will operate on via an
argument to your external.

2.
You can associate your pd external with a symbol using the function

void *pd_bind*(t_pd *x, t_symbol *s)

...where you pass the struct of your external as the "x" argument (you can easily cast it to t_pd). What this means in effect is that you can get a pointer to that structure from another external with the already
introduced *pd_findbyclass* function, by passing it as arguments the
registered symbol and the *t_class* of the registered external.
Again, it is a good idea to let the user choose the registered symbol
via an argument of the external.

This effectively means that you can separate the functionality you
want to achieve into many externals, so that one allocates memory for
some data in its struct and the others will be able to operate on that
memory by accesing the struct of the registered external, while the
"invisible connections" are made via the symbols that the user gives
as arguments to the externals (we can say, by the names that the user
assigns to the instances of the externals).


If you have further questions, please ask!

hi Jakob,
I appreciate your contribution, but what I'm looking for is a general
purpose, so probably I want to do exactly what I ask.

for sure, if I'll need to interface with arrays I'll use your proposed
solution number 2, but here I'm developing a meta-external (tclpd, a
toolkit for writing externals in Tcl language) so it has to be general
purpose.


What Jakob outlines are the two methods of getting array data when writing an external in C. If you are talking about creating a Tcl API to Pd arrays, I think there should be a Tcl equivalent of those two options. If that's not what you mean, then perhaps you could illustrate the idea more?

.hc


----------------------------------------------------------------------------

There is no way to peace, peace is the way.       -A.J. Muste



_______________________________________________
Pd-dev mailing list
Pd-dev@iem.at
http://lists.puredata.info/listinfo/pd-dev

Reply via email to