[gst-devel] float caps, category, audioconvert changes

Ronald Bultje rbultje at ronald.bitfreak.net
Sun Jul 20 01:23:12 CEST 2003


On Sun, 2003-07-20 at 02:34, David Schleef wrote:
> On Sat, Jul 19, 2003 at 07:53:41PM -0400, Leif Johnson wrote:
> > I'm still working on fully integrating float audio into the audioconvert
> > plugin. If anyone has a quick macro to change the endianness of a float or
> > double, I could use one. :) I'll check in my float changes as soon as they
> > work for me, but the int side of things should hopefully still work.
> GUINT32_TO_LE() and GUINT64_TO_LE().

Do UINT functions work for FLOAT types, too? As far as I understand, it
will just cast it to a guint64 and return it as such, too.

[rbultje at shrek tmp]$ grep GUINT64_TO_LE glibconfig.h
#define GUINT64_TO_LE(val)      ((guint64) (val))
[rbultje at shrek tmp]$

http://www.starlink.rl.ac.uk/star/docs/sc13.htx/N-a2b3c2.html has some
info on float representations (though nothing about doubles :(), and it
seems the byteorder layout is the same as for ints (that's in the first
part). From what I understand, an endianness conversion thing could look
like this (similar to ints):

#ifdef (BYTE_ORDER == G_LITTLE_ENDIAN)
#define GFLOAT_FROM_LE(x) ((gfloat)(x))
#define GFLOAT_TO_LE(x) (GFLOAT_FROM_LE(x))
#define GFLOAT_FROM_BE(x) (gfloat_byteswap(x))
#define GFLOAT_TO_BE(x) (GFLOAT_FROM_BE(x))
#else
#define GFLOAT_FROM_LE(x) (gfloat_byteswap(x))
#define GFLOAT_TO_LE(x) (GFLOAT_FROM_LE(x))
#define GFLOAT_FROM_BE(x) ((gfloat)(x))
#define GFLOAT_TO_BE(x) (GFLOAT_FROM_BE(x))
#endif

byteswap:

static inline gfloat
gfloat_byteswap (gfloat in)
{
  guint32 bytes = * (guint32 *) ∈
#ifdef (BYTE_ORDER == G_BIG_ENDIAN)
  bytes = GUINT32_FROM_LE(bytes);
#else
  bytes = GUINT32_FROM_BE(bytes);
#endif
  return * (gfloat *) &bytes;
}

Or so. The double would look the same, but 64 bit:

#ifdef (BYTE_ORDER == G_LITTLE_ENDIAN)
#define GDOUBLE_FROM_LE(x) ((gdouble)(x))
#define GDOUBLE_TO_LE(x) (GDOUBLE_FROM_LE(x))
#define GDOUBLE_FROM_BE(x) (gdouble_byteswap(x))
#define GDOUBLE_TO_BE(x) (GDOUBLE_FROM_BE(x))
#else
#define GDOUBLE_FROM_LE(x) (gdouble_byteswap(x))
#define GDOUBLE_TO_LE(x) (GDOUBLE_FROM_LE(x))
#define GDOUBLE_FROM_BE(x) ((gdouble)(x))
#define GDOUBLE_TO_BE(x) (GDOUBLE_FROM_BE(x))
#endif

static inline gdouble
gdouble_byteswap (gdouble in)
{
  guint64 bytes = * (guint64 *) ∈
#ifdef (BYTE_ORDER == G_BIG_ENDIAN)
  bytes = GUINT64_FROM_LE(bytes);
#else
  bytes = GUINT64_FROM_BE(bytes);
#endif
  return * (gdouble *) &bytes;
}

Could you test these in a row (i.e. start with your own endianness, go
to the other and go back) and see if the data still works? If so, you
could try to make a file and let people with the "other" endianness read
it and see if it works for them. If so, we've got a winner.

In all the above, I'm assuming that byte order is the only issue here,
and that the order of mantissa, sign etc. doesn't change (as the IEEE
seems to prescribe). I'm not sure of this at all, since I've never known
a single thing about floats. ;).

Ronald

-- 
Ronald Bultje <rbultje at ronald.bitfreak.net>





More information about the gstreamer-devel mailing list