Hi all, Speex currently decides endianness at configure-time. This causes the ppc half of Mac universal binaries to have some endianness problems. Most notably, the header built by speex_packet_to_header() has incorrect byte-ordering. This Apple developer page describes the incantation that can be used to build universal binaries on Mac. It also highlights the configure-time versus compile-time endianess problem http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html I have included a patch that applies Apple's recommendation to use the gcc-defined __BIG_ENDIAN__ preprocessor variable to determine endianness at compile-time. This technique works like a champ on Mac. It also works fine on Linux variants with modern a modern gcc. And Windows works like before. The patch was made against the head of the subversion trunk. Hope this helps. Pete -------------- next part -------------- A non-text attachment was scrubbed... Name: speex-ppc-endianness.patch Type: text/x-patch Size: 1240 bytes Desc: not available Url : http://lists.xiph.org/pipermail/speex-dev/attachments/20070502/9a81b8c4/speex-ppc-endianness.bin
Well, I don't quite understand why AC_C_BIGENDIAN and the solution you're proposing is likely to break other big endian machines (the ones that don't have __BIG_ENDIAN__). Can you send a patch that addresses that (i.e. still uses AC_C_BIGENDIAN when it works)? Jean-Marc Peter Grayson a ?crit :> Hi all, > > Speex currently decides endianness at configure-time. This causes the > ppc half of Mac universal binaries to have some endianness problems. > Most notably, the header built by speex_packet_to_header() has > incorrect byte-ordering. > > This Apple developer page describes the incantation that can be used > to build universal binaries on Mac. It also highlights the > configure-time versus compile-time endianess problem > > http://developer.apple.com/documentation/Porting/Conceptual/PortingUnix/compiling/chapter_4_section_3.html > > > I have included a patch that applies Apple's recommendation to use the > gcc-defined __BIG_ENDIAN__ preprocessor variable to determine > endianness at compile-time. This technique works like a champ on Mac. > It also works fine on Linux variants with modern a modern gcc. And > Windows works like before. > > The patch was made against the head of the subversion trunk. > > Hope this helps. > > Pete > > > ------------------------------------------------------------------------ > > Index: src/wav_io.h > ==================================================================> --- src/wav_io.h (revision 12905) > +++ src/wav_io.h (working copy) > @@ -35,7 +35,7 @@ > #include <stdio.h> > #include "speex/speex_types.h" > > -#ifdef WORDS_BIGENDIAN > +#ifdef __BIG_ENDIAN__ > #define le_short(s) ((short) ((unsigned short) (s) << 8) | ((unsigned short) (s) >> 8)) > #define be_short(s) ((short) (s)) > #else > @@ -46,7 +46,7 @@ > /** Convert little endian */ > static inline spx_int32_t le_int(spx_int32_t i) > { > -#ifdef WORDS_BIGENDIAN > +#ifdef __BIG_ENDIAN__ > spx_uint32_t ui, ret; > ui = i; > ret = ui>>24; > Index: configure.ac > ==================================================================> --- configure.ac (revision 12905) > +++ configure.ac (working copy) > @@ -32,7 +32,6 @@ > AC_CANONICAL_HOST > AM_PROG_LIBTOOL > > -AC_C_BIGENDIAN > AC_C_CONST > AC_C_INLINE > AC_C_RESTRICT > Index: libspeex/misc.h > ==================================================================> --- libspeex/misc.h (revision 12905) > +++ libspeex/misc.h (working copy) > @@ -78,7 +78,7 @@ > /** Convert little endian */ > static inline spx_int32_t le_int(spx_int32_t i) > { > -#ifdef WORDS_BIGENDIAN > +#ifdef __BIG_ENDIAN__ > spx_uint32_t ui, ret; > ui = i; > ret = ui>>24; > > > ------------------------------------------------------------------------ > > _______________________________________________ > Speex-dev mailing list > Speex-dev@xiph.org > http://lists.xiph.org/mailman/listinfo/speex-dev
On 5/2/07, Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> wrote:> Well, I don't quite understand why AC_C_BIGENDIAN and the solution > you're proposing is likely to break other big endian machines (the ones > that don't have __BIG_ENDIAN__). Can you send a patch that addresses > that (i.e. still uses AC_C_BIGENDIAN when it works)?It is not that AC_C_BIGENDIAN does not work. It is that it determines endianness at configure-time as opposed to compile-time. The process for building universal binaries on Mac demands that the distinction be made at compile-time. To enable building universal binaries on Mac in a single pass, the decision has to be deferred to compile-time. My strong suspicion is that testing __BIG_ENDIAN__ at compile-time will work for all relevant unix-like platforms. Even icc supports this. The extra thing we could do is set a preprocessor variable at configure-time that we could use at compile-time to determine whether the endianess was resolved at configure-time or should be resolved at compile-time. For example: #if defined(COMPILE_TIME_ENDIANESS) && defined(__BIG_ENDIAN__) || !defined(COMPILE_TIME_ENDIANESS) && defined(WORDS_BIGENDIAN) /* do big endian thing */ #else /* do little endian thing */ #endif This seems excessively complicated, so I preferred not to do it. Can others comment on the availability of the compiler defined __BIG_ENDIAN__ and __LITTLE_ENDIAN__ variables? Pete
> It is not that AC_C_BIGENDIAN does not work. It is that it determines > endianness at configure-time as opposed to compile-time. The process > for building universal binaries on Mac demands that the distinction be > made at compile-time. To enable building universal binaries on Mac in > a single pass, the decision has to be deferred to compile-time.I don't quite see the major difference between doing things at configure time or at compile time, bug anyway...> My strong suspicion is that testing __BIG_ENDIAN__ at compile-time > will work for all relevant unix-like platforms. Even icc supports > this.My suspicion is that I don't want to break things because MacOS X has strange requirements.> The extra thing we could do is set a preprocessor variable at > configure-time that we could use at compile-time to determine whether > the endianess was resolved at configure-time or should be resolved at > compile-time. For example: > > #if defined(COMPILE_TIME_ENDIANESS) && defined(__BIG_ENDIAN__) || > !defined(COMPILE_TIME_ENDIANESS) && defined(WORDS_BIGENDIAN) > /* do big endian thing */ > #else > /* do little endian thing */ > #endif > > This seems excessively complicated, so I preferred not to do it.Actually, all we need is to do is have that once in the main include: #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) #define SPEEX_BIGENDIAN #endif and then we just use SPEEX_BIGENDIAN everywhere else. Jean-Marc
On 5/3/07, Jean-Marc Valin <jean-marc.valin@usherbrooke.ca> wrote:> I don't quite see the major difference between doing things at configure > time or at compile time, bug anyway...Sorry, I was not clear. The thing that is unique about the Mac build process is that it shares the same configuration for both x86 and ppc builds. It also uses a single compiler invocation for both where __BIG_ENDIAN__ is defined ppc and __LITTLE_ENDIAN__ for x86.> My suspicion is that I don't want to break things because MacOS X has > strange requirements.I suspect your suspicion to be quite valid. Agreed.> > > The extra thing we could do is set a preprocessor variable at > > configure-time that we could use at compile-time to determine whether > > the endianess was resolved at configure-time or should be resolved at > > compile-time. For example: > > > > #if defined(COMPILE_TIME_ENDIANESS) && defined(__BIG_ENDIAN__) || > > !defined(COMPILE_TIME_ENDIANESS) && defined(WORDS_BIGENDIAN) > > /* do big endian thing */ > > #else > > /* do little endian thing */ > > #endif > > > > This seems excessively complicated, so I preferred not to do it. > > Actually, all we need is to do is have that once in the main include: > #if defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) > #define SPEEX_BIGENDIAN > #endif > > and then we just use SPEEX_BIGENDIAN everywhere else.This technique would work for in all cases except when building the universal binary on a ppc machine. In that case, both WORDS_BIGENDIAN and __LITTLE_ENDIAN__ will be defined at compile time (for the x86 part of the build). Maybe if we amended the expression to this: #if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) ) ... I think that would cover all the bases. I have attached a patch that makes this change. There is a little code duplication because wavio.h and misc.h both need this trick, but they don't appear to share any headers besides speex_types.h. I wasn't sure if speex_types.h was a good place for this or not. Pete -------------- next part -------------- A non-text attachment was scrubbed... Name: speex-ppc-endianness2.patch Type: text/x-patch Size: 1290 bytes Desc: not available Url : http://lists.xiph.org/pipermail/speex-dev/attachments/20070503/bfde8f58/speex-ppc-endianness2.bin