Attached is a patch that should make flext buffer handling 64-bit compatible.

It adds new wrapper functions buffer::Peek(int index) and
buffer::Poke(int index, t_sample value) to access a buffer's data. New
externals should uses these instead of accessing the data array
directly, because with newer PDs that doesn't work. I've also updated
the buffer1 example to use the new API wrappers.

The issue is that arrays in PD are of type t_word, which is a union
that can contain a variety of data, including pointers. In 32-bit
architectures you can pretty much ignore that it's a union because
floats and pointers are the same size, but on 64-bit architectures
it's important to use the w_float member of the union to access stored
floats.

This patch shouldn't break any old externals unless they're used with
PD > 0.41 (but then they'd be broken, anyways). I don't have access to
an OS X machine or Max/MSP, so I've so far only tested this on 64-bit
linux/PD. YMMV.

Can someone explain to me why pd's arrays are arrays of t_word instead
of t_sample?

-s-

On Thu, Oct 1, 2009 at 10:41 AM, dmotd <dm...@gmx.net> wrote:
> hi spencer,
>
> afaik there hasn't been any progress with
> the 64bit translation, i was going to
> attempt it last time i needed it but got
> distracted along the way - and i sent a
> similar message to thomas at the time, so
> its going to be on his todo list, but
> proabably not a priority.
>
> i'd be happy to test any changes you
> make, and collaborate time permitted.
>
> ciao,
>
> dmotd
>
> Spencer Russell wrote:
>> Thought this should probably go to the list:
>>
>> ---------- Forwarded message ----------
>> From: Spencer Russell <spencer.f.russ...@gmail.com>
>> Date: Tue, Sep 29, 2009 at 11:13 AM
>> Subject: Re: fixing Flext for 64-bit?
>> To: Thomas Grill <g...@grrrr.org>
>>
>> >
>> > Am 29.09.2009 um 15:00 schrieb Spencer Russell:
>> >
>> >> Hi Thomas,
>> >>
>> >> I'm writing a Flext external to implement Iannis Xenakis's Dynamic
>> >> Stochastic Synthesis, and running into some problems with buffer
>> >> handling on my 64-bit system.
>> >>
>> >> It seems that currently flext uses the deprecated
>> >> garray_getfloatarray() function and t_sample arrays, instead of the
>> >> new garray_getfloatwords() function with t_word unions.
>> >>
>> >> Changing the code would make flext incompatible with older versions of
>> >> PD, but some other external developers are currently using an #ifdef
>> >> workaround to change to the newer API call for PD versions that
>> >> support it.
>> >>
>> >> I was going to get in there and see if i can't get it working in the
>> >> flext code, but I wanted to check with you first to see if you had
>> >> already done any work on that front. I'll of course send you the diffs
>> >> if i get it working. Shouldn't be that hard and i think it should
>> >> really only effect the buffer-handling code, but I don't know the
>> >> flext codebase that well so there  might be some hidden gotchas.
>> >>
>> >> -spencer
>>
>> On Tue, Sep 29, 2009 at 9:08 AM, Thomas Grill <g...@grrrr.org> wrote:
>> > Hi Spencer,
>> > i know that this is something i should work on, but my schedule is insanely
>> > tight and i don't get to it.
>> > So, if you can make any contributions and testing on 64-bit systems i'd be
>> > very grateful.
>> > I'd also go for the Pd API selecton by #ifdef statements.
>> > gr~~~
>> >
>>
>> As far as i can tell, PD since 0.41 changed arrays to be arrays of
>> t_words instead of t_samples or t_floats.
>>
>> On 32-bit architectures they're all the same size, but on 64-bit
>> architectures t_word is 64-bit, while t_sample and t_float are still
>> 32-bit.
>>
>> For a normal PD external, it's pretty easy to just modify the external
>> to use t_words, but I'm not sure the best way to modify flext to do
>> this without breaking compatibility for externals. One problem is that
>> when an external calls mybuffer.Data(), what should they receive? if
>> the system is PD newer than 0.41, they should receive a pointer to
>> t_word, but MAX or older PD should receive a pointer to t_sample.
>>
>> The other problem is that accessing an element for newer PD requires
>> accessing the w_float member of the t_word union, but the others just
>> use the element itself.
>>
>> There could be some sort of GetValue() wrapper for buffer elements
>> that could be made cross-platform, but would break compatibility with
>> existing flext externals, so that seems seriously sub-optimal.
>>
>> thoughts?
>>
>> -s-
>> _______________________________________________
>> http://grrrr.org/ext/flext
>>
>> flext mailing list
>> fl...@grrrr.org
>> http://www.parasitaere-kapazitaeten.net/mailman/listinfo/flext
>
diff --git a/source/flbuf.cpp b/source/flbuf.cpp
index b200d52..8ff0a70 100644
--- a/source/flbuf.cpp
+++ b/source/flbuf.cpp
@@ -101,7 +101,7 @@ int flext::buffer::Set(const t_symbol *s,bool nameonly)
     else if(!nameonly) {
 #if FLEXT_SYS == FLEXT_SYS_PD
         int frames1;
-        t_sample *data1;
+        FLEXT_ARRAYTYPE *data1;
     
         arr = (t_garray *)pd_findbyclass(const_cast<t_symbol *>(sym), garray_class);
         if(!arr)
@@ -110,7 +110,7 @@ int flext::buffer::Set(const t_symbol *s,bool nameonly)
 //            sym = NULL;
             if(valid) ret = -1;
         }
-        else if(!garray_getfloatarray(arr, &frames1, &data1))
+        else if(!FLEXT_ARRAYGRAB(arr, &frames1, &data1))
         {
             error("buffer: bad template '%s'",GetString(sym)); 
             data = NULL;
@@ -165,8 +165,8 @@ bool flext::buffer::Update()
     if(!arr) return data == NULL;
 
     int frames1;
-    t_sample *data1;
-    if(!garray_getfloatarray(arr, &frames1, &data1)) {
+    FLEXT_ARRAYTYPE *data1;
+    if(!FLEXT_ARRAYGRAB(arr, &frames1, &data1)) {
         data = NULL;
         chns = 0;
         frames = 0;
diff --git a/source/flsupport.h b/source/flsupport.h
index 3ddb7be..f730c54 100644
--- a/source/flsupport.h
+++ b/source/flsupport.h
@@ -203,7 +203,27 @@ public:
 #else
 #error Not implemented
 #endif
-    
+
+
+// PD 64-bit buffer handling macros
+#if FLEXT_SYS == FLEXT_SYS_PD
+#       if PD_MINOR_VERSION >= 41
+                /* use new garray support that is 64-bit safe */
+#               define FLEXT_ARRAYGRAB garray_getfloatwords
+#               define FLEXT_ARRAYTYPE t_word
+#               define FLEXT_GETELEMENT(arr,x) (arr)[(x)].w_float
+
+#       else
+                /* use old garray support, not 64-bit safe */
+#               define FLEXT_ARRAYGRAB garray_getfloatarray
+#               define FLEXT_ARRAYTYPE t_sample
+#               define FLEXT_GETELEMENT(arr,x) (arr)[(x)]
+#       endif
+#elif FLEXT_SYS == FLEXT_SYS_MAX
+#       define FLEXT_ARRAYTYPE t_sample
+#       define FLEXT_GETELEMENT(arr,x) (arr)[(x)]
+#endif
+
         /*! \brief Construct buffer.
             \param s: symbol name, can be NULL
             \param delayed = true: only sets name, needs another Set(NULL) to really initialize the buffer 
@@ -287,7 +307,7 @@ public:
         /*! \brief Get pointer to buffer, channel and frame count.
             \remark Channels are interleaved
         */
-        t_sample *Data() { return data; }
+        FLEXT_ARRAYTYPE *Data() { return data; }
 
         //! Get channel count
         int Channels() const { return chns; }
@@ -295,6 +315,12 @@ public:
         int Frames() const { return frames; }
         //! Set frame count
         void Frames(int fr,bool keep = false,bool zero = true);
+
+        //! Get a data value in a platform-independent way
+        inline t_sample Peek(int index) { return FLEXT_GETELEMENT(data,index); }
+
+        //! Set a data value in a platform-independent way
+        inline void Poke(int index, t_sample value) { FLEXT_GETELEMENT(data,index) = value; }
         
         //! Graphic auto refresh interval
         void SetRefrIntv(float intv);
@@ -314,7 +340,7 @@ public:
         //! buffer name
         const t_symbol *sym;
         //! array holding audio data
-        t_sample *data;
+        FLEXT_ARRAYTYPE *data;
         //! number of audio channels
         int chns;
         //! number of frames (multiplied by chns for the number of samples)
diff --git a/tutorial/buffer1/main.cpp b/tutorial/buffer1/main.cpp
index 7f604c8..478dab4 100755
--- a/tutorial/buffer1/main.cpp
+++ b/tutorial/buffer1/main.cpp
@@ -215,8 +215,9 @@ void buffer1::m_poke(int argc,const t_atom *argv)
 		ok = false;
 		
 	if(ok) {
-		// correct syntax, set sample
-		buf->Data()[ix] = val;
+		// correct syntax, set sample and trigger display
+		buf->Poke(ix, val);
+		buf->Dirty(true);
 	}
 	else
 		post("%s (%s) - syntax error - use \"poke index value [channel]\"",thisName(),GetString(thisTag()));
@@ -246,8 +247,8 @@ void buffer1::m_peek(int argc,const t_atom *argv)
 		ok = false;
 		
 	if(ok)
-		// correct syntax, output value
-		ToOutFloat(0,buf->Data()[ix]);
+		// correct syntax, output value 
+		ToOutFloat(0,buf->Peek(ix));
 	else
 		post("%s (%s) - syntax error - use \"peek index [channel]\"",thisName(),GetString(thisTag()));
 }
_______________________________________________
Pd-dev mailing list
Pd-dev@iem.at
http://lists.puredata.info/listinfo/pd-dev

Reply via email to