[gst-devel] One more step on the road to gstreamer enlightenment

Erik Walthinsen omega at temple-baptist.com
Sat Aug 31 19:23:01 CEST 2002


On 1 Sep 2002, iain wrote:

> for (i = 0; i < GST_BUFFER_SIZE (buf); i++) {
> 	int16_t d = *((int16_t *)(GST_BUFFER_DATA (buf) + i));
> 	out_bufs[0][i] = ((float) d) / 32767.0;
> /* 	g_print ("d: %d -> %f\n", d, out_bufs[0][i]); */
> }

This should read something like:

GstBuffer *intbuf;
gint16 *ints;
gint numsamples;
gint i;
gfloat *floats;
GstBuffer *floatbuf;

// Get a buffer full of 2-byte wide samples
intbuf = gst_pad_pull(....);
// Get a int16 pointer to the data
ints = (gint16 *)GST_BUFFER_DATA(intbuf);
// Calculate how many samples there are in the buffer
numsamples = GST_BUFFER_SIZE(intbuf) / sizeof(gint16);

// Allocate a new buffer for the 4-byte wide floats
floatbuf = gst_buffer_new_and_alloc(numsamples * sizeof(gfloat));
// Get the float pointer to the new data
floats = (gfloat *)GST_BUFFER_DATA(floatbuf);

// Copy the samples
for (i=0; i<numsamples; i++)
  floats[i] = (gfloat)ints[i] / 32767.0;

// Free the old int16 buffer
gst_buffer_unref(intbuf);
// Send the new float buffer
gst_pad_push(...., floatbuf);


There are several problems with your original code:

1) it overwrites data in the GstBuffer without checking READONLY or other
   flags
2) it assumes that int16 and float are the same size, which they're not,
   floats are 32-bit
3) the iterator 'i' is incremented for every byte in the buffer, not for
   every sample
4) every other int16 is taken from a non-aligned (odd) byte position, and
   the float is written to the same place, overwriting subsequent samples
   and getting bogus data on all but the first sample, and trashing the
   first sample with the 2nd, 3rd, and 4th

The first problem is solved by allocating a new buffer.  Second is solved
by allocating the right size, after calculating the actual sample count.
Third is solved by casting the pointer to the right type (GstBuffer is a
byte pointer, adding 'i' to it *inside* the cast gives byte offsets,
adding it *outside* the int16 cast gives word offsets).  Fourth is solved
by using the appropriate offsets by using array operations on the typecast
pointers.

None of this is specific to GStreamer, however.

      Erik Walthinsen <omega at temple-baptist.com> - System Administrator
        __
       /  \                GStreamer - The only way to stream!
      |    | M E G A        ***** http://gstreamer.net/ *****
      _\  /_






More information about the gstreamer-devel mailing list